| File: | kauth/klog.c |
| Location: | line 285, column 2 |
| Description: | Value stored to 'lclpw' is never read |
| 1 | /* |
| 2 | * Copyright 2000, International Business Machines Corporation and others. |
| 3 | * All Rights Reserved. |
| 4 | * |
| 5 | * This software has been released under the terms of the IBM Public |
| 6 | * License. For details, see the LICENSE file in the top-level source |
| 7 | * directory or online at http://www.openafs.org/dl/license10.html |
| 8 | */ |
| 9 | |
| 10 | #include <afsconfig.h> |
| 11 | #include <afs/param.h> |
| 12 | #include <afs/stds.h> |
| 13 | |
| 14 | #include <roken.h> |
| 15 | |
| 16 | #include <rx/xdr.h> |
| 17 | #include <lock.h> |
| 18 | #include <ubik.h> |
| 19 | #include <afs/com_err.h> |
| 20 | #include <afs/cellconfig.h> |
| 21 | #include <afs/cmd.h> |
| 22 | |
| 23 | #include "kauth.h" |
| 24 | #include "kautils.h" |
| 25 | #include "kauth_internal.h" |
| 26 | #include "assert.h" |
| 27 | |
| 28 | |
| 29 | /* This code borrowed heavily from the previous version of log. Here is the |
| 30 | intro comment for that program: */ |
| 31 | |
| 32 | /* |
| 33 | log -- tell the Andrew Cache Manager your password |
| 34 | 5 June 1985 |
| 35 | modified |
| 36 | February 1986 |
| 37 | |
| 38 | Further modified in August 1987 to understand cell IDs. |
| 39 | */ |
| 40 | |
| 41 | /* Current Usage: |
| 42 | klog [principal [password]] [-t] [-c cellname] [-servers <hostlist>] |
| 43 | |
| 44 | where: |
| 45 | principal is of the form 'name' or 'name@cell' which provides the |
| 46 | cellname. See the -c option below. |
| 47 | password is the user's password. This form is NOT recommended for |
| 48 | interactive users. |
| 49 | -t advises klog to write a Kerberos style ticket file in /tmp. |
| 50 | -c identifies cellname as the cell in which authentication is to take |
| 51 | place. |
| 52 | -servers allows the explicit specification of the hosts providing |
| 53 | authentication services for the cell being used for authentication. |
| 54 | */ |
| 55 | |
| 56 | #define KLOGEXIT(code)((!code || code >= (180480L)) ? (void)0 : __assert(__func__ , "klog.c", 56, "!code || code >= KAMINERROR")); rx_Finalize (); (!code ? exit(0) : exit((code)-(180480L)+1)) assert(!code || code >= KAMINERROR)((!code || code >= (180480L)) ? (void)0 : __assert(__func__ , "klog.c", 56, "!code || code >= KAMINERROR")); \ |
| 57 | rx_Finalize(); \ |
| 58 | (!code ? exit(0) : exit((code)-KAMINERROR(180480L)+1)) |
| 59 | int CommandProc(struct cmd_syndesc *as, void *arock); |
| 60 | |
| 61 | static int zero_argc; |
| 62 | static char **zero_argv; |
| 63 | |
| 64 | int |
| 65 | osi_audit(void) |
| 66 | { |
| 67 | return 0; |
| 68 | } |
| 69 | |
| 70 | int |
| 71 | main(int argc, char *argv[]) |
| 72 | { |
| 73 | struct cmd_syndesc *ts; |
| 74 | afs_int32 code; |
| 75 | #ifdef AFS_AIX32_ENV |
| 76 | /* |
| 77 | * The following signal action for AIX is necessary so that in case of a |
| 78 | * crash (i.e. core is generated) we can include the user's data section |
| 79 | * in the core dump. Unfortunately, by default, only a partial core is |
| 80 | * generated which, in many cases, isn't too useful. |
| 81 | */ |
| 82 | struct sigaction nsa; |
| 83 | |
| 84 | sigemptyset(&nsa.sa_mask); |
| 85 | nsa.sa_handler__sigaction_u.__sa_handler = SIG_DFL((__sighandler_t *)0); |
| 86 | nsa.sa_flags = SA_FULLDUMP; |
| 87 | sigaction(SIGABRT6, &nsa, NULL((void *)0)); |
| 88 | sigaction(SIGSEGV11, &nsa, NULL((void *)0)); |
| 89 | #endif |
| 90 | zero_argc = argc; |
| 91 | zero_argv = argv; |
| 92 | |
| 93 | ts = cmd_CreateSyntax(NULL((void *)0), CommandProc, NULL((void *)0), |
| 94 | "obtain Kerberos authentication"); |
| 95 | |
| 96 | #define aXFLAG0 0 |
| 97 | #define aPRINCIPAL1 1 |
| 98 | #define aPASSWORD2 2 |
| 99 | #define aCELL3 3 |
| 100 | #define aSERVERS4 4 |
| 101 | #define aPIPE5 5 |
| 102 | #define aSILENT6 6 |
| 103 | #define aLIFETIME7 7 |
| 104 | #define aSETPAG8 8 |
| 105 | #define aTMP9 9 |
| 106 | |
| 107 | |
| 108 | cmd_AddParm(ts, "-x", CMD_FLAG1, CMD_OPTIONAL1, "(obsolete, noop)"); |
| 109 | cmd_Seek(ts, aPRINCIPAL1); |
| 110 | cmd_AddParm(ts, "-principal", CMD_SINGLE2, CMD_OPTIONAL1, "user name"); |
| 111 | cmd_AddParm(ts, "-password", CMD_SINGLE2, CMD_OPTIONAL1, "user's password"); |
| 112 | cmd_AddParm(ts, "-cell", CMD_SINGLE2, CMD_OPTIONAL1, "cell name"); |
| 113 | cmd_AddParm(ts, "-servers", CMD_LIST3, CMD_OPTIONAL1, |
| 114 | "explicit list of servers"); |
| 115 | cmd_AddParm(ts, "-pipe", CMD_FLAG1, CMD_OPTIONAL1, |
| 116 | "read password from stdin"); |
| 117 | cmd_AddParm(ts, "-silent", CMD_FLAG1, CMD_OPTIONAL1, "silent operation"); |
| 118 | cmd_AddParm(ts, "-lifetime", CMD_SINGLE2, CMD_OPTIONAL1, |
| 119 | "ticket lifetime in hh[:mm[:ss]]"); |
| 120 | cmd_AddParm(ts, "-setpag", CMD_FLAG1, CMD_OPTIONAL1, |
| 121 | "Create a new setpag before authenticating"); |
| 122 | cmd_AddParm(ts, "-tmp", CMD_FLAG1, CMD_OPTIONAL1, |
| 123 | "write Kerberos-style ticket file in /tmp"); |
| 124 | |
| 125 | code = cmd_Dispatch(argc, argv); |
| 126 | KLOGEXIT(code)((!code || code >= (180480L)) ? (void)0 : __assert(__func__ , "klog.c", 126, "!code || code >= KAMINERROR")); rx_Finalize (); (!code ? exit(0) : exit((code)-(180480L)+1)); |
| 127 | } |
| 128 | |
| 129 | static char * |
| 130 | getpipepass(void) |
| 131 | { |
| 132 | static char gpbuf[BUFSIZ1024]; |
| 133 | /* read a password from stdin, stop on \n or eof */ |
| 134 | int i, tc; |
| 135 | memset(gpbuf, 0, sizeof(gpbuf)); |
| 136 | for (i = 0; i < (sizeof(gpbuf) - 1); i++) { |
| 137 | tc = fgetc(stdin__stdinp); |
| 138 | if (tc == '\n' || tc == EOF(-1)) |
| 139 | break; |
| 140 | gpbuf[i] = tc; |
| 141 | } |
| 142 | return gpbuf; |
| 143 | } |
| 144 | |
| 145 | int |
| 146 | CommandProc(struct cmd_syndesc *as, void *arock) |
| 147 | { |
| 148 | char name[MAXKTCNAMELEN64]; |
| 149 | char instance[MAXKTCNAMELEN64]; |
| 150 | char cell[MAXKTCREALMLEN64]; |
| 151 | char realm[MAXKTCREALMLEN64]; |
| 152 | afs_uint32 serverList[MAXSERVERS20]; |
| 153 | char *lcell; /* local cellname */ |
| 154 | char lrealm[MAXKTCREALMLEN64]; /* uppercase copy of local cellname */ |
| 155 | int code; |
| 156 | int i, dosetpag; |
| 157 | Dateafs_uint32 lifetime; /* requested ticket lifetime */ |
| 158 | |
| 159 | struct passwd pwent; |
| 160 | struct passwd *pw = &pwent; |
| 161 | struct passwd *lclpw = &pwent; |
| 162 | char passwd[BUFSIZ1024]; |
| 163 | |
| 164 | static char rn[] = "klog"; /*Routine name */ |
| 165 | static int Pipe = 0; /* reading from a pipe */ |
| 166 | static int Silent = 0; /* Don't want error messages */ |
| 167 | |
| 168 | int explicit; /* servers specified explicitly */ |
| 169 | int local; /* explicit cell is same a local one */ |
| 170 | int foundPassword = 0; /*Not yet, anyway */ |
| 171 | int foundExplicitCell = 0; /*Not yet, anyway */ |
| 172 | int writeTicketFile = 0; /* write ticket file to /tmp */ |
| 173 | afs_int32 password_expires = -1; |
| 174 | |
| 175 | char *reason; /* string describing errors */ |
| 176 | |
| 177 | /* blow away command line arguments */ |
| 178 | for (i = 1; i < zero_argc; i++) |
| 179 | memset(zero_argv[i], 0, strlen(zero_argv[i])); |
| 180 | zero_argc = 0; |
| 181 | |
| 182 | /* first determine quiet flag based on -silent switch */ |
| 183 | Silent = (as->parms[aSILENT6].items ? 1 : 0); |
| 184 | Pipe = (as->parms[aPIPE5].items ? 1 : 0); |
| 185 | |
| 186 | /* Determine if we should also do a setpag based on -setpag switch */ |
| 187 | dosetpag = (as->parms[aSETPAG8].items ? 1 : 0); |
| 188 | |
| 189 | if (as->parms[aTMP9].items) { |
| 190 | writeTicketFile = 1; |
| 191 | } |
| 192 | |
| 193 | if (as->parms[aCELL3].items) { |
| 194 | /* |
| 195 | * cell name explicitly mentioned; take it in if no other cell name |
| 196 | * has already been specified and if the name actually appears. If |
| 197 | * the given cell name differs from our own, we don't do a lookup. |
| 198 | */ |
| 199 | foundExplicitCell = 1; |
| 200 | strncpy(realm, as->parms[aCELL3].items->data, sizeof(realm)); |
| 201 | /* XXX the following is just a hack to handle the afscell environment XXX */ |
| 202 | (void)afsconf_GetCellInfo((struct afsconf_dir *)0, realm, 0, |
| 203 | (struct afsconf_cell *)0); |
| 204 | } |
| 205 | |
| 206 | code = ka_Init(0); |
| 207 | if (code || !(lcell = ka_LocalCell())) { |
| 208 | nocell: |
| 209 | if (!Silent) |
| 210 | afs_com_err(rn, code, "Can't get local cell name!"); |
| 211 | KLOGEXIT(code)((!code || code >= (180480L)) ? (void)0 : __assert(__func__ , "klog.c", 211, "!code || code >= KAMINERROR")); rx_Finalize (); (!code ? exit(0) : exit((code)-(180480L)+1)); |
| 212 | } |
| 213 | if ((code = ka_CellToRealm(lcell, lrealm, 0))) |
| 214 | goto nocell; |
| 215 | |
| 216 | strcpy(instance, ""); |
| 217 | |
| 218 | /* Parse our arguments. */ |
| 219 | |
| 220 | if (as->parms[aCELL3].items) { |
| 221 | /* |
| 222 | * cell name explicitly mentioned; take it in if no other cell name |
| 223 | * has already been specified and if the name actually appears. If |
| 224 | * the given cell name differs from our own, we don't do a lookup. |
| 225 | */ |
| 226 | foundExplicitCell = 1; |
| 227 | strncpy(realm, as->parms[aCELL3].items->data, sizeof(realm)); |
| 228 | } |
| 229 | |
| 230 | if (as->parms[aSERVERS4].items) { |
| 231 | /* explicit server list */ |
| 232 | int i; |
| 233 | struct cmd_item *ip; |
| 234 | char *ap[MAXSERVERS20 + 2]; |
| 235 | |
| 236 | for (ip = as->parms[aSERVERS4].items, i = 2; ip; ip = ip->next, i++) |
| 237 | ap[i] = ip->data; |
| 238 | ap[0] = ""; |
| 239 | ap[1] = "-servers"; |
| 240 | code = ubik_ParseClientList(i, ap, serverList); |
| 241 | if (code) { |
| 242 | if (!Silent) { |
| 243 | afs_com_err(rn, code, "could not parse server list"); |
| 244 | } |
| 245 | return code; |
| 246 | } |
| 247 | explicit = 1; |
| 248 | } else |
| 249 | explicit = 0; |
| 250 | |
| 251 | if (as->parms[aPRINCIPAL1].items) { |
| 252 | ka_ParseLoginName(as->parms[aPRINCIPAL1].items->data, name, instance, |
| 253 | cell); |
| 254 | if (strlen(instance) > 0) |
| 255 | if (!Silent) { |
| 256 | fprintf(stderr__stderrp, |
| 257 | "Non-null instance (%s) may cause strange behavior.\n", |
| 258 | instance); |
| 259 | } |
| 260 | if (strlen(cell) > 0) { |
| 261 | if (foundExplicitCell) { |
| 262 | if (!Silent) { |
| 263 | fprintf(stderr__stderrp, |
| 264 | "%s: May not specify an explicit cell twice.\n", |
| 265 | rn); |
| 266 | } |
| 267 | return -1; |
| 268 | } |
| 269 | foundExplicitCell = 1; |
| 270 | strncpy(realm, cell, sizeof(realm)); |
| 271 | } |
| 272 | lclpw->pw_name = name; |
| 273 | } else { |
| 274 | /* No explicit name provided: use Unix uid. */ |
| 275 | pw = getpwuid(getuid()); |
| 276 | if (pw == 0) { |
| 277 | if (!Silent) { |
| 278 | fprintf(stderr__stderrp, |
| 279 | "Can't figure out your name in local cell %s from your user id.\n", |
| 280 | lcell); |
| 281 | fprintf(stderr__stderrp, "Try providing the user name.\n"); |
| 282 | } |
| 283 | KLOGEXIT(KABADARGUMENT)((!(180492L) || (180492L) >= (180480L)) ? (void)0 : __assert (__func__, "klog.c", 283, "!(180492L) || (180492L) >= KAMINERROR" )); rx_Finalize(); (!(180492L) ? exit(0) : exit(((180492L))-( 180480L)+1)); |
| 284 | } |
| 285 | lclpw = pw; |
Value stored to 'lclpw' is never read | |
| 286 | } |
| 287 | |
| 288 | if (as->parms[aPASSWORD2].items) { |
| 289 | /* |
| 290 | * Current argument is the desired password string. Remember it in |
| 291 | * our local buffer, and zero out the argument string - anyone can |
| 292 | * see it there with ps! |
| 293 | */ |
| 294 | foundPassword = 1; |
| 295 | strncpy(passwd, as->parms[aPASSWORD2].items->data, sizeof(passwd)); |
| 296 | memset(as->parms[aPASSWORD2].items->data, 0, |
| 297 | strlen(as->parms[aPASSWORD2].items->data)); |
| 298 | } |
| 299 | |
| 300 | if (as->parms[aLIFETIME7].items) { |
| 301 | char *life = as->parms[aLIFETIME7].items->data; |
| 302 | char *sp; /* string ptr to rest of life */ |
| 303 | lifetime = 3600 * strtol(life, &sp, 0); /* hours */ |
| 304 | if (sp == life) { |
| 305 | bad_lifetime: |
| 306 | if (!Silent) |
| 307 | fprintf(stderr__stderrp, "%s: translating '%s' to lifetime failed\n", |
| 308 | rn, life); |
| 309 | return KABADARGUMENT(180492L); |
| 310 | } |
| 311 | if (*sp == ':') { |
| 312 | life = sp + 1; /* skip the colon */ |
| 313 | lifetime += 60 * strtol(life, &sp, 0); /* minutes */ |
| 314 | if (sp == life) |
| 315 | goto bad_lifetime; |
| 316 | if (*sp == ':') { |
| 317 | life = sp + 1; |
| 318 | lifetime += strtol(life, &sp, 0); /* seconds */ |
| 319 | if (sp == life) |
| 320 | goto bad_lifetime; |
| 321 | if (*sp) |
| 322 | goto bad_lifetime; |
| 323 | } else if (*sp) |
| 324 | goto bad_lifetime; |
| 325 | } else if (*sp) |
| 326 | goto bad_lifetime; |
| 327 | if (lifetime > MAXKTCTICKETLIFETIME(30*24*3600)) { |
| 328 | if (!Silent) |
| 329 | fprintf(stderr__stderrp, |
| 330 | "%s: a lifetime of %.2f hours is too long, must be less than %d.\n", |
| 331 | rn, (double)lifetime / 3600.0, |
| 332 | MAXKTCTICKETLIFETIME(30*24*3600) / 3600); |
| 333 | KLOGEXIT(KABADARGUMENT)((!(180492L) || (180492L) >= (180480L)) ? (void)0 : __assert (__func__, "klog.c", 333, "!(180492L) || (180492L) >= KAMINERROR" )); rx_Finalize(); (!(180492L) ? exit(0) : exit(((180492L))-( 180480L)+1)); |
| 334 | } |
| 335 | } else |
| 336 | lifetime = 0; |
| 337 | |
| 338 | if (!foundExplicitCell) |
| 339 | strcpy(realm, lcell); |
| 340 | if ((code = ka_CellToRealm(realm, realm, &local))) { |
| 341 | if (!Silent) |
| 342 | afs_com_err(rn, code, "Can't convert cell to realm"); |
| 343 | KLOGEXIT(code)((!code || code >= (180480L)) ? (void)0 : __assert(__func__ , "klog.c", 343, "!code || code >= KAMINERROR")); rx_Finalize (); (!code ? exit(0) : exit((code)-(180480L)+1)); |
| 344 | } |
| 345 | |
| 346 | /* Get the password if it wasn't provided. */ |
| 347 | if (!foundPassword) { |
| 348 | if (Pipe) { |
| 349 | strncpy(passwd, getpipepass(), sizeof(passwd)); |
| 350 | } else { |
| 351 | if (ka_UserReadPassword |
| 352 | ("Password:", passwd, sizeof(passwd), &reason)) { |
| 353 | fprintf(stderr__stderrp, "Unable to login because %s.\n", reason); |
| 354 | KLOGEXIT(KABADARGUMENT)((!(180492L) || (180492L) >= (180480L)) ? (void)0 : __assert (__func__, "klog.c", 354, "!(180492L) || (180492L) >= KAMINERROR" )); rx_Finalize(); (!(180492L) ? exit(0) : exit(((180492L))-( 180480L)+1)); |
| 355 | } |
| 356 | } |
| 357 | } |
| 358 | |
| 359 | if (explicit) |
| 360 | ka_ExplicitCell(realm, serverList); |
| 361 | |
| 362 | code = |
| 363 | ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION1 + |
| 364 | (dosetpag ? KA_USERAUTH_DOSETPAG20x020000 : 0), |
| 365 | pw->pw_name, instance, realm, passwd, |
| 366 | lifetime, &password_expires, 0, &reason); |
| 367 | memset(passwd, 0, sizeof(passwd)); |
| 368 | if (code) { |
| 369 | if (!Silent) { |
| 370 | fprintf(stderr__stderrp, "Unable to authenticate to AFS because %s.\n", |
| 371 | reason); |
| 372 | } |
| 373 | KLOGEXIT(code)((!code || code >= (180480L)) ? (void)0 : __assert(__func__ , "klog.c", 373, "!code || code >= KAMINERROR")); rx_Finalize (); (!code ? exit(0) : exit((code)-(180480L)+1)); |
| 374 | } |
| 375 | #ifndef AFS_KERBEROS_ENV |
| 376 | if (writeTicketFile) { |
| 377 | code = krb_write_ticket_file(realm); |
| 378 | if (!Silent) { |
| 379 | if (code) |
| 380 | afs_com_err(rn, code, "writing Kerberos ticket file"); |
| 381 | else |
| 382 | fprintf(stderr__stderrp, "Wrote ticket file to /tmp\n"); |
| 383 | } |
| 384 | } |
| 385 | #endif |
| 386 | |
| 387 | #ifdef DEBUGEXPIRES |
| 388 | if (password_expires >= 0) { |
| 389 | printf("password expires at %ld\n", password_expires); |
| 390 | } |
| 391 | #endif /* DEBUGEXPIRES */ |
| 392 | |
| 393 | return 0; |
| 394 | } |