static int get_cellconfig(char *cell, struct afsconf_cell *cellconfig, char *local_cell) { int status = AKLOG_SUCCESS; struct afsconf_dir *configdir = 0; memset(local_cell, 0, sizeof(local_cell)); memset(cellconfig, 0, sizeof(*cellconfig)); if (GetLocalCell(&configdir, local_cell)) { fprintf(stderr, "%s: can't determine local cell.\n", progname); akexit(AKLOG_AFS); } if ((cell == NULL) || (cell[0] == 0)) cell = local_cell; if (GetCellInfo(&configdir, cell, &cellconfig)) { fprintf(stderr, "%s: Can't get information about cell %s.\n", progname, cell); status = AKLOG_AFS; } if (cellconfig->linkedCell) cellconfig->linkedCell = strdup(cellconfig->linkedCell); CloseConf(&configdir); return(status); }
/* Print usage message and exit */ static void usage(void) { fprintf(stderr, "\nUsage: %s %s%s%s%s\n", progname, "[-d] [[-cell | -c] cell [-k krb_realm]] ", "[[-p | -path] pathname]\n", " [-noprdb] [-force]\n", #ifdef HAVE_KRB4 " [-5 [-m]| -4]\n" #else " [-5]\n" #endif ); fprintf(stderr, " -d gives debugging information.\n"); fprintf(stderr, " krb_realm is the kerberos realm of a cell.\n"); fprintf(stderr, " pathname is the name of a directory to which "); fprintf(stderr, "you wish to authenticate.\n"); fprintf(stderr, " -noprdb means don't try to determine AFS ID.\n"); #ifdef HAVE_KRB4 fprintf(stderr, " -5 or -4 selects whether to use Kerberos v5 or Kerberos v4.\n" " (default is Kerberos v5)\n"); fprintf(stderr, " -m means use krb524d to convert Kerberos v5 tickets.\n"); #else fprintf(stderr, " -5 use Kerberos v5.\n" " (only Kerberos v5 is available)\n"); #endif fprintf(stderr, " No commandline arguments means "); fprintf(stderr, "authenticate to the local cell.\n"); fprintf(stderr, "\n"); akexit(AKLOG_USAGE); }
void validate_krb4_availability(void) { #ifdef HAVE_KRB4 HINSTANCE h = LoadLibrary("krbv4w32.dll"); if (h) FreeLibrary(h); else { fprintf(stderr, "Kerberos for Windows library krbv4w32.dll is not available.\n"); akexit(AKLOG_KFW_NOT_INSTALLED); } #else fprintf(stderr, "Kerberos v4 is not available in this build of aklog.\n"); akexit(AKLOG_USAGE); #endif }
void validate_krb5_availability(void) { if (!DelayLoadHeimdal()) { fprintf(stderr, "Kerberos for Windows or Heimdal is not available.\n"); akexit(AKLOG_KFW_NOT_INSTALLED); } }
long GetLocalCell(struct afsconf_dir **pconfigdir, char *local_cell) { if (!(*pconfigdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) { fprintf(stderr, "%s: can't get afs configuration (afsconf_Open(%s))\n", progname, AFSDIR_CLIENT_ETC_DIRPATH); akexit(AKLOG_AFS); } return afsconf_GetLocalCell(*pconfigdir, local_cell, MAXCELLCHARS); }
void validate_krb5_availability(void) { HINSTANCE h = LoadLibrary(KRB5LIB); if (h) FreeLibrary(h); else { fprintf(stderr, "Kerberos for Windows library %s is not available.\n", KRB5LIB); akexit(AKLOG_KFW_NOT_INSTALLED); } }
void validate_krb5_availability(void) { #ifndef _WIN64 #define KRB5LIB "krb5_32.dll" #else #define KRB5LIB "krb5_64.dll" #endif HINSTANCE h = LoadLibrary(KRB5LIB); if (h) FreeLibrary(h); else { fprintf(stderr, "Kerberos for Windows library %s is not available.\n", KRB5LIB); akexit(AKLOG_KFW_NOT_INSTALLED); } }
int main(int argc, char *argv[]) { int status = AKLOG_SUCCESS; int i; int somethingswrong = FALSE; cellinfo_t cellinfo; extern char *progname; /* Name of this program */ extern int dflag; /* Debug mode */ int cmode = FALSE; /* Cellname mode */ int pmode = FALSE; /* Path name mode */ char realm[REALM_SZ]; /* Kerberos realm of afs server */ char cell[BUFSIZ]; /* Cell to which we are authenticating */ char path[MAXPATHLEN + 1]; /* Path length for path mode */ linked_list cells; /* List of cells to log to */ linked_list paths; /* List of paths to log to */ ll_node *cur_node; memset(&cellinfo, 0, sizeof(cellinfo)); memset(realm, 0, sizeof(realm)); memset(cell, 0, sizeof(cell)); memset(path, 0, sizeof(path)); ll_init(&cells); ll_init(&paths); /* Store the program name here for error messages */ if (progname = LastComponent(argv[0])) progname++; else progname = argv[0]; /* Initialize list of cells to which we have authenticated */ (void)ll_init(&authedcells); /* Parse commandline arguments and make list of what to do. */ for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-d") == 0) dflag++; else if (strcmp(argv[i], "-5") == 0) usev5++; #ifdef HAVE_KRB4 else if (strcmp(argv[i], "-m") == 0) use524++; else if (strcmp(argv[i], "-4") == 0) usev5 = 0; #endif else if (strcmp(argv[i], "-noprdb") == 0) noprdb++; else if (strcmp(argv[i], "-force") == 0) force++; else if (((strcmp(argv[i], "-cell") == 0) || (strcmp(argv[i], "-c") == 0)) && !pmode) { if (++i < argc) { cmode++; strcpy(cell, argv[i]); } else usage(); } else if (((strcmp(argv[i], "-path") == 0) || (strcmp(argv[i], "-p") == 0)) && !cmode) { if (++i < argc) { pmode++; strcpy(path, argv[i]); } else usage(); } else if (argv[i][0] == '-') usage(); else if (!pmode && !cmode) { if (FirstComponent(argv[i]) || (strcmp(argv[i], ".") == 0) || (strcmp(argv[i], "..") == 0)) { pmode++; strcpy(path, argv[i]); } else { cmode++; strcpy(cell, argv[i]); } } else usage(); if (cmode) { if (((i + 1) < argc) && (strcmp(argv[i + 1], "-k") == 0)) { i += 2; if (i < argc) strcpy(realm, argv[i]); else usage(); } /* Add this cell to list of cells */ strcpy(cellinfo.cell, cell); strcpy(cellinfo.realm, realm); if (cur_node = ll_add_node(&cells, ll_tail)) { char *new_cellinfo; if (new_cellinfo = copy_cellinfo(&cellinfo)) ll_add_data(cur_node, new_cellinfo); else { fprintf(stderr, "%s: failure copying cellinfo.\n", progname); akexit(AKLOG_MISC); } } else { fprintf(stderr, "%s: failure adding cell to cells list.\n", progname); akexit(AKLOG_MISC); } memset(&cellinfo, 0, sizeof(cellinfo)); cmode = FALSE; memset(cell, 0, sizeof(cell)); memset(realm, 0, sizeof(realm)); } else if (pmode) { /* Add this path to list of paths */ if (cur_node = ll_add_node(&paths, ll_tail)) { char *new_path; if (new_path = strdup(path)) ll_add_data(cur_node, new_path); else { fprintf(stderr, "%s: failure copying path name.\n", progname); akexit(AKLOG_MISC); } } else { fprintf(stderr, "%s: failure adding path to paths list.\n", progname); akexit(AKLOG_MISC); } pmode = FALSE; memset(path, 0, sizeof(path)); } } if (!noprdb) initialize_PT_error_table(); if (usev5) { validate_krb5_availability(); if (krb5_init_context(&context)) return(AKLOG_KERBEROS); load_krb5_error_message_funcs(); } else validate_krb4_availability(); afs_set_com_err_hook(redirect_errors); /* If nothing was given, log to the local cell. */ if ((cells.nelements + paths.nelements) == 0) status = auth_to_cell(context, NULL, NULL); else { /* Log to all cells in the cells list first */ for (cur_node = cells.first; cur_node; cur_node = cur_node->next) { memcpy(&cellinfo, cur_node->data, sizeof(cellinfo)); if (status = auth_to_cell(context, cellinfo.cell, cellinfo.realm)) somethingswrong++; } /* Then, log to all paths in the paths list */ for (cur_node = paths.first; cur_node; cur_node = cur_node->next) { if (status = auth_to_path(context, cur_node->data)) somethingswrong++; } /* * If only one thing was logged to, we'll return the status * of the single call. Otherwise, we'll return a generic * something failed status. */ if (somethingswrong && ((cells.nelements + paths.nelements) > 1)) status = AKLOG_SOMETHINGSWRONG; } akexit(status); }
/* * This routine descends through a path to a directory, logging to * every cell it encounters along the way. */ static int auth_to_path(krb5_context context, char *path) { int status = AKLOG_SUCCESS; int auth_to_cell_status = AKLOG_SUCCESS; char *nextpath; char pathtocheck[MAXPATHLEN + 1]; char mountpoint[MAXPATHLEN + 1]; char *cell; char *endofcell; /* Initialize */ if (BeginsWithDir(path, TRUE)) strcpy(pathtocheck, path); else { if (getcwd(pathtocheck, sizeof(pathtocheck)) == NULL) { fprintf(stderr, "Unable to find current working directory:\n"); fprintf(stderr, "%s\n", pathtocheck); fprintf(stderr, "Try an absolute pathname.\n"); akexit(AKLOG_BADPATH); } else { /* in WIN32, if getcwd returns a root dir (eg: c:\), the returned string * will already have a trailing slash ('\'). Otherwise, the string will * end in the last directory name */ #ifdef WIN32 if(pathtocheck[strlen(pathtocheck) - 1] != BDIR) #endif strcat(pathtocheck, DIRSTRING); strcat(pathtocheck, path); } } next_path(pathtocheck); /* Go on to the next level down the path */ while (nextpath = next_path(NULL)) { strcpy(pathtocheck, nextpath); if (dflag) printf("Checking directory [%s]\n", pathtocheck); /* * If this is an afs mountpoint, determine what cell from * the mountpoint name which is of the form * #cellname:volumename or %cellname:volumename. */ if (get_afs_mountpoint(pathtocheck, mountpoint, sizeof(mountpoint))) { if(dflag) printf("Found mount point [%s]\n", mountpoint); /* skip over the '#' or '%' */ cell = mountpoint + 1; if (endofcell = strchr(mountpoint, VOLMARKER)) { *endofcell = '\0'; if (auth_to_cell_status = auth_to_cell(context, cell, NULL)) { if (status == AKLOG_SUCCESS) status = auth_to_cell_status; else if (status != auth_to_cell_status) status = AKLOG_SOMETHINGSWRONG; } } } else { struct stat st; if (lstat(pathtocheck, &st) < 0) { /* * If we've logged and still can't stat, there's * a problem... */ fprintf(stderr, "%s: stat(%s): %s\n", progname, pathtocheck, strerror(errno)); return(AKLOG_BADPATH); } else if (!S_ISDIR(st.st_mode)) { /* Allow only directories */ fprintf(stderr, "%s: %s: %s\n", progname, pathtocheck, strerror(ENOTDIR)); return(AKLOG_BADPATH); } } } return(status); }
/* * This routine each time it is called returns the next directory * down a pathname. It resolves all symbolic links. The first time * it is called, it should be called with the name of the path * to be descended. After that, it should be called with the arguemnt * NULL. */ static char *next_path(char *origpath) { static char path[MAXPATHLEN + 1]; static char pathtocheck[MAXPATHLEN + 1]; int link = FALSE; /* Is this a symbolic link? */ char linkbuf[MAXPATHLEN + 1]; char tmpbuf[MAXPATHLEN + 1]; static char *last_comp; /* last component of directory name */ static char *elast_comp; /* End of last component */ char *t; int len; static int symlinkcount = 0; /* We can't exceed MAXSYMLINKS */ /* If we are given something for origpath, we are initializing only. */ if (origpath) { memset(path, 0, sizeof(path)); memset(pathtocheck, 0, sizeof(pathtocheck)); CopyPathColon(origpath, path, pathtocheck); last_comp = path; symlinkcount = 0; return(NULL); } /* We were not given origpath; find then next path to check */ /* If we've gotten all the way through already, return NULL */ if (last_comp == NULL) return(NULL); do { while (BeginsWithDir(last_comp, FALSE)) strncat(pathtocheck, last_comp++, 1); len = (int) ((elast_comp = LastComponent(last_comp)) ? elast_comp - last_comp : strlen(last_comp)); strncat(pathtocheck, last_comp, len); memset(linkbuf, 0, sizeof(linkbuf)); if (link = (readlink(pathtocheck, linkbuf, sizeof(linkbuf)) > 0)) { if (++symlinkcount > MAXSYMLINKS) { fprintf(stderr, "%s: %s\n", progname, strerror(ELOOP)); akexit(AKLOG_BADPATH); } memset(tmpbuf, 0, sizeof(tmpbuf)); if (elast_comp) strcpy(tmpbuf, elast_comp); if (BeginsWithDir(linkbuf, FALSE)) { /* * If this is a symbolic link to an absolute path, * replace what we have by the absolute path. */ memset(path, 0, strlen(path)); memcpy(path, linkbuf, sizeof(linkbuf)); strcat(path, tmpbuf); last_comp = path; elast_comp = NULL; memset(pathtocheck, 0, sizeof(pathtocheck)); } else { /* * If this is a symbolic link to a relative path, * replace only the last component with the link name. */ strncpy(last_comp, linkbuf, strlen(linkbuf) + 1); strcat(path, tmpbuf); elast_comp = NULL; if (t = LastComponent(pathtocheck)) { t++; memset(t, 0, strlen(t)); } else memset(pathtocheck, 0, sizeof(pathtocheck)); } } else last_comp = elast_comp; } while(link); return(pathtocheck); }