X-Git-Url: https://git.hcoop.net/hcoop/debian/libnss-afs.git/blobdiff_plain/908a6ebee13783def6d4af79efb7ac61dc3075b2..b5f46b9e4196461e47d8c0baa061660f0d1e2d48:/nss_afs.c diff --git a/nss_afs.c b/nss_afs.c index 3ef57b9..de52438 100644 --- a/nss_afs.c +++ b/nss_afs.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -78,6 +79,7 @@ #define MAX_OLDPAG_GID 0xff00 #define MAXCELLNAMELEN 256 +#define MAXUSERNAMELEN 256 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; @@ -86,6 +88,7 @@ extern struct ubik_client *pruclient; int afs_initialized = 0; char cellname[MAXCELLNAMELEN]; char homedir_prefix[MAXPATHLEN]; +char cell_root[MAXPATHLEN]; int homedir_prefix_len=0; char homedirs_method=0; char shells_method=0; @@ -113,7 +116,7 @@ enum nss_status ptsid2name(int uid, char **buffer, int *buflen) { idlist lid; namelist lnames; - init_afs(); + if (init_afs()) return NSS_STATUS_UNAVAIL; if (uid==AFS_MAGIC_ANONYMOUS_USERID) { if (!cpstr("anonymous", buffer, buflen)) return NSS_STATUS_UNAVAIL; @@ -128,6 +131,7 @@ enum nss_status ptsid2name(int uid, char **buffer, int *buflen) { lnames.namelist_len = 0; if (ubik_Call(PR_IDToName,pruclient,0,&lid,&lnames) != PRSUCCESS) { + perror("ubik_Call() in ptsid2name() failed\n"); pthread_mutex_unlock(&mutex); return NSS_STATUS_UNAVAIL; } @@ -156,8 +160,9 @@ enum nss_status ptsname2id(char *name, uid_t* uid) { int res; idlist lid; namelist lnames; + char uname[MAXUSERNAMELEN]; - init_afs(); + if (init_afs()) return NSS_STATUS_UNAVAIL; if (!strcmp(name,"anonymous")) { *uid = AFS_MAGIC_ANONYMOUS_USERID; @@ -168,10 +173,13 @@ enum nss_status ptsname2id(char *name, uid_t* uid) { lid.idlist_val = 0; lid.idlist_len = 0; - lnames.namelist_val = (prname*)name; + lnames.namelist_val = (prname*)uname; + // apparently ubik expects to be able to modify this? + strncpy(uname, name, MAXUSERNAMELEN); lnames.namelist_len = 1; if (ubik_Call(PR_NameToID,pruclient,0,&lnames,&lid) != PRSUCCESS) { + perror("ubik_Call() in ptsname2id() failed\n"); pthread_mutex_unlock(&mutex); return NSS_STATUS_UNAVAIL; } @@ -189,9 +197,38 @@ enum nss_status ptsname2id(char *name, uid_t* uid) { int init_afs() { FILE *thiscell; int len; + struct stat statbuf; + + char buf[6]; + int fd; + int pos; - if (afs_initialized) return 0; + if (afs_initialized) { + /* wait until /afs/@cell/ appears as a proxy for "the network is up" */ + if (stat(cell_root, &statbuf)) return -1; + return 0; + } + // check to make sure that we are running inside nscd + pos = 0; + fd = open("/proc/self/cmdline", O_RDONLY); + if (fd==-1) return -1; + while(1) { + int numread; + numread = read(fd, buf+pos, 1); + if (buf[ (pos+5)%6 ] == 'd' && + buf[ (pos+4)%6 ] == 'c' && + buf[ (pos+3)%6 ] == 's' && + buf[ (pos+2)%6 ] == 'n' && + (buf[(pos+1)%6 ] == '/' || pos==4) && + (buf[(pos+0)%6 ] == 0 || numread==-1) + ) + break; + pos = (pos+1)%6; + if (numread==0) { close(fd); return -1; } + } + close(fd); + if (pthread_mutex_lock(&mutex)) return -1; do { homedirs_method=HOMEDIR_PREFIX; @@ -215,10 +252,21 @@ int init_afs() { if (cellname[len-1] == '\n') len--; cellname[len]='\0'; + + /* wait until /afs/@cell/ appears as a proxy for "the network is up" */ + sprintf(cell_root,"/afs/%s/",cellname); + if (stat(cell_root, &statbuf)) break; + sprintf(homedir_prefix,"/afs/%s/user/",cellname); homedir_prefix_len=strlen(homedir_prefix); - - if (pr_Initialize(0L,AFSDIR_CLIENT_ETC_DIRPATH, 0)) break; + + /* time out requests after 5 seconds to avoid hanging things */ + rx_SetRxDeadTime(5); + + if (pr_Initialize(0L,AFSDIR_CLIENT_ETC_DIRPATH, 0)) { + perror("pr_Initialize() failed\n"); + break; + } afs_initialized = 1; pthread_mutex_unlock(&mutex); @@ -386,6 +434,14 @@ enum nss_status fill_result_buf(uid_t uid, result_buf->pw_shell = buffer; if ( get_shell(result_buf->pw_name,&buffer,&buflen) ) break; +#ifdef LIMIT_USERNAME_CHARS + if ( strlen(result_buf->pw_name) > LIMIT_USERNAME_CHARS ) { + result_buf->pw_name[LIMIT_USERNAME_CHARS] = '\0'; + buflen = buflen + ( buffer - &result_buf->pw_name[LIMIT_USERNAME_CHARS+1] ); + buffer = &result_buf->pw_name[LIMIT_USERNAME_CHARS+1]; + } +#endif + *errnop = errno; return NSS_STATUS_SUCCESS; } while(0); @@ -417,14 +473,6 @@ enum nss_status _nss_afs_getpwuid_r (uid_t uid, return temp; } -#ifdef LIMIT_USERNAME_CHARS - if ( strlen(result_buf->pw_name) > LIMIT_USERNAME_CHARS ) { - result_buf->pw_name[LIMIT_USERNAME_CHARS] = '\0'; - buflen = buflen + ( buffer - &result_buf->pw_name[LIMIT_USERNAME_CHARS+1] ); - buffer = &result_buf->pw_name[LIMIT_USERNAME_CHARS+1]; - } -#endif - return fill_result_buf(uid, name, result_buf, buffer, buflen, errnop); }