Skip to content

Commit 207fc48

Browse files
committed
Make accountadm work on modern Debian
sql.mit.edu Debian-based servers need admof, just like the Fedora-based realservers. Unfortunately, there seem to be some differences in how Debian and Fedora currently handle OpenAFS packaging and dependencies, so the admof does not build as-is. Namely, the krb5 function krb5_524_conv_principal no longer exists in MIT krb5, so we have to implement it ourselves. The implementation comes from openafs' aklog.c, modified to fit the expected function signature. OpenAFS also throws a surprise at us: it needs heimdal to link (namely, libroken and libhcrypto). This adds another challenge to admof, as it now has to juggle mit-krb5 and heimdal-krb5 at build-time. This change continues to use mit-krb5, but has #if 0'd out heimdal implementation if we ever change our minds. Making this work required re-writing the autotools configuration. I've replaced it with a modern configure.ac and Makefile.am. Rewrite autotools to be modern; update admof to link against new openafs
1 parent 842d8c2 commit 207fc48

File tree

8 files changed

+677
-74
lines changed

8 files changed

+677
-74
lines changed
Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,19 @@
1-
/configure
2-
/autom4te.cache
1+
configure
2+
autom4te.cache
3+
Makefile
4+
Makefile.in
5+
config.*
6+
compile
7+
install-sh
8+
ssh-admof
9+
depcomp
10+
INSTALL
11+
.deps
12+
ar-lib
13+
missing
14+
stamp-h1
15+
aclocal.m4
16+
admof
17+
*.o
18+
mbash
19+
signup-scripts-backend
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
bin_PROGRAMS = admof
2+
3+
admof_SOURCES = admof.c
4+
admof_LDADD = @KRB5_LIBS@ @HEIMDAL_LIBS@ @PTHREAD_LIBS@
5+
admof_CFLAGS = @KRB5_CFLAGS@
6+
7+
ssh-admof: admof
8+
@cp -p $< $@
9+
CLEANFILES = ssh-admof
10+
11+
dist_bin_SCRIPTS = mbash cronload
12+
dist_sbin_SCRIPTS = \
13+
get-homedirs \
14+
ldap-backup \
15+
signup-scripts-backend \
16+
ssh-admof \
17+
vhostadd \
18+
vhostedit
19+
dist_sysconf_DATA = mbashrc

server/common/oursrc/accountadm/Makefile.in

Lines changed: 0 additions & 33 deletions
This file was deleted.

server/common/oursrc/accountadm/admof.c

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ extern int pioctl(char *, afs_int32, struct ViceIoctl *, afs_int32);
5252
_x > _y ? _x : _y; })
5353
#endif
5454

55+
#define get_princ_str(c, p, n) krb5_princ_component(c, p, n)->data
56+
#define get_princ_len(c, p, n) krb5_princ_component(c, p, n)->length
57+
#define second_comp(c, p) (krb5_princ_size(c, p) > 1)
58+
#define realm_data(c, p) krb5_princ_realm(c, p)->data
59+
#define realm_len(c, p) krb5_princ_realm(c, p)->length
60+
5561
#define SYSADMINS "system:scripts-root"
5662
#define SYSADMIN_CELL "athena.mit.edu"
5763

@@ -106,6 +112,44 @@ parse_rights(int n, const char **p, char *user)
106112
return rights;
107113
}
108114

115+
static int
116+
admof_krb5_524_conv_principal(krb5_context context, krb5_const_principal princ,
117+
char *name, char *inst, char *realm) {
118+
size_t len = 0;
119+
/* Taken from aklog.c in openafs and modified */
120+
len = min(get_princ_len(context, princ, 0),
121+
second_comp(context, princ) ?
122+
PR_MAXNAMELEN - 2 : PR_MAXNAMELEN - 1);
123+
strncpy(name, get_princ_str(context, princ, 0), len);
124+
name[len] = '\0';
125+
126+
if (second_comp(context, princ)) {
127+
len = min(get_princ_len(context, princ, 1),
128+
PR_MAXNAMELEN - strlen(name) - 1);
129+
strncpy(inst, get_princ_str(context, princ, 1), len);
130+
inst[len] = '\0';
131+
}
132+
realm[0] = '\0';
133+
#if 0
134+
// This code works for Heimdal krb5
135+
if (princ->name.name_string.len < 1) {
136+
return -1;
137+
}
138+
strncpy(name, princ->name.name_string.val[0], ANAME_SZ);
139+
name[ANAME_SZ-1] = '\0';
140+
if (princ->name.name_string.len > 1) {
141+
strncpy(inst, princ->name.name_string.val[1], ANAME_SZ);
142+
inst[ANAME_SZ-1] = '\0';
143+
}
144+
realm[0] = '\0';
145+
if (princ->realm) {
146+
strncpy(realm, princ->realm, ANAME_SZ);
147+
}
148+
realm[ANAME_SZ-1] = '\0';
149+
#endif
150+
return 0;
151+
}
152+
109153
/* Resolve a Kerberos principal to a name usable by the AFS PTS. */
110154
void
111155
resolve_principal(const char *name, const char *cell, char *user)
@@ -124,20 +168,30 @@ resolve_principal(const char *name, const char *cell, char *user)
124168
krb5_principal principal;
125169
if (krb5_parse_name(context, name, &principal) != 0)
126170
die("internal error: krb5_parse_name failed");
127-
char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
128-
if (krb5_524_conv_principal(context, principal, pname, pinst, prealm) != 0)
171+
char pname[ANAME_SZ] = {0}, pinst[INST_SZ] = {0}, prealm[REALM_SZ] = {0};
172+
if (admof_krb5_524_conv_principal(context, principal, pname, pinst, prealm) != 0)
129173
die("internal error: krb5_524_conv_principal failed\n");
130174

131175
krb5_data realm = *krb5_princ_realm(context, principal);
132176
if (realm.length > REALM_SZ - 1)
133-
realm.length = REALM_SZ - 1;
177+
realm.length = REALM_SZ - 1;
134178
if (strlen(realm_list[0]) == realm.length &&
135179
memcmp(realm.data, realm_list[0], realm.length) == 0)
136-
snprintf(user, MAX_K_NAME_SZ, "%s%s%s",
180+
snprintf(user, MAX_K_NAME_SZ, "%s%s%s",
181+
pname, pinst[0] ? "." : "", pinst);
182+
else
183+
snprintf(user, MAX_K_NAME_SZ, "%s%s%s@%.*s",
184+
pname, pinst[0] ? "." : "", pinst, realm.length, realm.data);
185+
186+
#if 0
187+
// This code works with Heimdal krb5
188+
if (strcmp(realm_list[0], prealm) == 0)
189+
snprintf(user, MAX_K_NAME_SZ, "%s%s%s",
137190
pname, pinst[0] ? "." : "", pinst);
138191
else
139-
snprintf(user, MAX_K_NAME_SZ, "%s%s%s@%.*s",
140-
pname, pinst[0] ? "." : "", pinst, realm.length, realm.data);
192+
snprintf(user, MAX_K_NAME_SZ, "%s%s%s@%s",
193+
pname, pinst[0] ? "." : "", pinst, prealm);
194+
#endif
141195

142196
krb5_free_principal(context, principal);
143197
krb5_free_host_realm(context, realm_list);
@@ -225,7 +279,7 @@ main(int argc, const char *argv[])
225279
}
226280

227281
/* Get the locker's cell. */
228-
char cell[MAXCELLCHARS];
282+
char cell[MAXCELLCHARS] = {0};
229283
struct ViceIoctl vi;
230284
vi.in = NULL;
231285
vi.in_size = 0;
@@ -245,12 +299,13 @@ main(int argc, const char *argv[])
245299
if (afsconf_GetCellInfo(configdir, cell, NULL, &cellconfig) != 0)
246300
die("internal error: afsconf_GetCellInfo failed\n");
247301
afsconf_Close(configdir);
302+
configdir = NULL;
248303

249304
char user[MAX(PR_MAXNAMELEN, MAX_K_NAME_SZ)];
250305
resolve_principal(name, cellconfig.hostName[0], user);
251306

252307
/* Read the locker ACL. */
253-
char acl[2048];
308+
char acl[2048] = {0};
254309
vi.in = NULL;
255310
vi.in_size = 0;
256311
vi.out = acl;
@@ -261,8 +316,8 @@ main(int argc, const char *argv[])
261316
/* Parse the locker ACL to compute the user's rights. */
262317
const char *p = acl;
263318

264-
int nplus, nminus;
265-
int off;
319+
int nplus = 0, nminus = 0;
320+
int off = 0;
266321
if (sscanf(p, "%d\n%d\n%n", &nplus, &nminus, &off) < 2)
267322
die("internal error: can't parse output from pioctl\n");
268323
p += off;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# -*- Autoconf -*-
2+
# Process this file with autoconf to produce a configure script.
3+
4+
AC_PREREQ([2.69])
5+
AC_INIT([scripts-accountadm], [0.1], [[email protected]])
6+
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
7+
AM_MAINTAINER_MODE([enable])
8+
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
9+
AC_CONFIG_MACRO_DIR([m4])
10+
AC_CONFIG_HEADERS([config.h])
11+
AC_USE_SYSTEM_EXTENSIONS
12+
13+
# Checks for programs.
14+
AC_PROG_CC
15+
# automake 1.12 seems to require this, but automake 1.11 doesn't recognize it
16+
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
17+
AC_PROG_INSTALL
18+
19+
# Checks for libraries.
20+
AC_CHECK_LIB([resolv], [res_mkquery], [], [
21+
AC_MSG_CHECKING([if res_mkquery is provided by libresolv with mangled symbols])
22+
save_LIBS="$LIBS"
23+
LIBS="-lresolv $LIBS"
24+
AC_TRY_LINK([#include <resolv.h>],
25+
[res_mkquery(0,NULL,0,0,NULL,0,NULL,NULL,0);], [
26+
AC_DEFINE(HAVE_LIBRESOLV, [1], [Define if your libresolv provides res_mkquery.])
27+
AC_MSG_RESULT(yes)], [
28+
LIBS="$save_LIBS"
29+
AC_MSG_RESULT(no)])])
30+
31+
AX_PTHREAD
32+
# MIT KRB5 is used for actual linking and runtime
33+
PKG_CHECK_MODULES([KRB5], [mit-krb5])
34+
# But OpenAFS needs heimdal libraries to operate
35+
PKG_CHECK_MODULES([HEIMDAL], [heimdal-krb5])
36+
AC_CHECK_LIB([roken], [rk_asnprintf], [], [], [$HEIMDAL_LIBS])
37+
AC_CHECK_LIB([hcrypto], [hc_RAND_bytes], [], [], [$HEIMDAL_LIBS])
38+
AC_CHECK_LIB([afsrpc_pic], [rx_GetCall], [], [], [$PTHREAD_LIBS $HEIMDAL_LIBS])
39+
AC_CHECK_LIB([afsauthent_pic], [afsconf_Open], [], [], [$PTHREAD_LIBS $HEIMDAL_LIBS])
40+
41+
# Checks for header files.
42+
AC_CHECK_HEADERS([limits.h netinet/in.h string.h syslog.h unistd.h])
43+
44+
# Checks for typedefs, structures, and compiler characteristics.
45+
AC_CHECK_HEADER_STDBOOL
46+
AC_TYPE_SIZE_T
47+
AC_TYPE_SSIZE_T
48+
49+
# Checks for library functions.
50+
AC_FUNC_MALLOC
51+
AC_CHECK_FUNCS([strcasecmp])
52+
53+
# For mbash
54+
AC_PATH_PROG([bash_path], [bash])
55+
56+
# For signup-scripts-backend
57+
AC_PATH_PROG([hesinfo_path], [hesinfo])
58+
AC_PATH_PROG([ldapadd_path], [ldapadd])
59+
AC_PATH_PROG([sudo_path], [sudo])
60+
61+
AC_CONFIG_FILES([Makefile signup-scripts-backend mbash])
62+
AC_OUTPUT

server/common/oursrc/accountadm/configure.in

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
libtool.m4
2+
ltoptions.m4
3+
ltsugar.m4
4+
ltversion.m4
5+
lt~obsolete.m4

0 commit comments

Comments
 (0)