npd_svc.c revision 7d1e83948cb684521e72cab96020be241508f449
extern char *
ypfwd;
/* YP domain to fwd NIS+ req */ * service routine for first part of the nispasswd update * service routine for first part of the nispasswd update2 "nispasswd_authenticate_common_svc: Out of memory");
/* check if I'm running on the host == master(domain) */ /* get caller info. from auth_handle */ /* caller == admin ? ; Y -> skip checks, N -> do aging checks */ /* authenticated user, check if they are privileged */ /* "." + null + "." = 3 */ "_authenticate_: 'nobody' or NUL prinicipal set to '%s'",
prin);
* The credential information may have changed for the user, * we should refresh the cache to make sure or the user is * a different user and the necessary checks need to be made. /* check if there is a cached entry */ /* found an entry - check if it has expired */ * check if this attempt > max_attempts. "too many failed attempts for %s",
* a new session and we have an entry cached * but we have not reached max_attempts, so * just update entry with the new pass }
else {
/* entry has expired */ "no cache entry found for %s but the identifier is %d",
/* get passwd info for username */ "NIS+ error (%d) getting passwd entry for %s",
/* if user check if 'min' days have passed since 'lastchg' */ "password has not aged enough for %s",
/* if ans == NPD_NOSHDWINFO then aging cannot be enforced */ * Find out what key length and algorithm type we're dealing with. * This will check if the key_type exists in the /* generate CK (from P.c and S.d) */ "cannot generate common DES key for %s",
/* decrypt the passwd sent */ /* assign an ID and generate R on the first call of a session */ /* second or third attempt */ /* gen a new random val */ /* encrypt the passwd and compare with that stored in NIS+ */ "_authenticate_: pw decrypt failed");
/* cache relevant info */ /* found an entry, attempt == max_attempts */ * not really a system error but we * want the caller to think that 'cos * they are obviously trying to break-in. * Perhaps, we should not respond at all, * the client side would timeout. /* admin changing another users password */ * we have no idea where this admin's * passwd record is stored BUT we do know * where their PK cred(s) is stored from * the netname, so lets try to decrypt * the secret key(s) with the passwd that /* cache relevant info */ /* cache relevant info */ * service routine for second part of the nispasswd update * service routine for second part of the nispasswd update2 * service routine for second part of the nispasswd update common "nispasswd_update_common_svc: Out of memory");
/* set to success, and reset to error when warranted */ * iterate thru entry list and decrypt R sent and new passwd until * we have a rand hit (or reach end of list) /* decrypt R and new passwd */ /* decrypt R and new passwd */ "rand miss: entry rval=%ld; continue...",
/* create passwd struct with this pass & gecos/shell */ "NIS+ error (%d) getting passwd entry for %s",
/* can change passwd, shell or gecos */ /* clear out the error list */ /* if a gecos field is provided... */ "insufficient permission for %s to change the gecos",
/* if a shell field is provided... */ "insufficient permission for %s to change the shell",
* If already set to partial success, that means * that gecos field and error was provided, so * add the next item to the error list. /* update lstchg field in the shadow area */ /* clone an entry object to update passwd entry */ /* save the old values for restoring before freeing the object */ /* set column value to entry column */ /* strlen("[name=],passwd.") + null + "." = 17 */ /* put together table index info and object modification */ /* add dot "." if necessary */ /* update NIS+ passwd table */ /* if NIS+ update fails, bail now */ /* NIS+ master updated; if YP-forwarding turned on, do YP */ int try = 0;
/* retry counter for YP & NIS+ updates */ * Attempt the YP passwd map update; * on failures use exponential backoff * On repeated failures (MAX_RETRY), * give up & undo NIS+ table update try = 0;
/* clear for undo attempts */ "unable to update NIS(YP) passwd \ * The passwd tbl update failed, so set 'error' * to an NPD failure. Here is where it gets * tricky. The permissions on the passwd table * must be turned off because the failover mech- * anism will try to get NISD to make the update. /* set "new" passwd back to old password */ /* undo the NIS+ passwd table update */ /* exponential backoff each try */ * Update table with old passwd information, * freeing the old 'mod_res' struct first. * 'eobj' has already been set to 'ecol' above. /* On success, exit; otherwise increment ctr */ /* NIS+ update repeated failures, bail now and log */ passwd update; maybe out-of-sync with YP map -- verify by hand");
* The 'error' flag can only be changed from NPD_SUCCESS if * YP updating was on and then, only in a failure scenario. * In all other situations, update the credential! /* attempt to update PK cred(s) */ * Only set the reason union member if partial success; * otherwise may wipe out npd_err union member. /* Epilogue just consists of freeing up data */ /* Restore column stuff so that we can free eobj */ * The code to free pobj is not necessary as in * yppasswdproc_update_1_svc() because pobj is * freed when pass_res is just below. Otherwise * if it's in here, it will dump core. * yppasswd update service routine. * it seems that the client side only checks if the result is * non-zero in which case it prints a generic message ! /* set new password from YP passwd struct */ "received yp password update request from %s",
/* fill-in NIS+ server information */ * make the nis_stats call to check if the server is running * in compat mode and get the list of directories this server "NIS+ server does not support the new statistics tags");
/* check if server is running in NIS compat mode */ "Local NIS+ server is not running in NIS compat mode");
* find the dir that has a passwd entry for this user * POLICY: if user has a passwd stored in more then one * dir then do not make an update. if user has an entry * in only one dir, then make an update in that dir. /* if ans == NPD_NOSHDWINFO then aging cannot be enforced */ /* validate the old passwd */ *
result =
7;
/* password incorrect */ /* mismatch on old passwd */ /* can change passwd, gecos or shell */ /* need to strip org_dir part of the domain */ /* "." + null + "." = 3 */ "insufficient permission for %s to change the gecos",
"insufficient permission for %s to change the shell",
* This fixes a really bogus security hole, basically anyone can * call the rpc passwd daemon, give them their own passwd and a * new one that consists of ':0:0:Im root now:/:/bin/csh^J' and * give themselves root access. With this code it will simply make * it impossible for them to login again, and as a bonus leave * a cookie for the always vigilant system administrator to ferret *p =
'$';
/* you lose ! */ *p =
'$';
/* you lose ! */ /* update lstchg field */ /* clone an entry object to update passwd entry */ /* save the old values to restore while freeing the object */ /* set column value to entry column */ /* strlen("[name=],passwd.") + null + "." = 17 */ /* put together table index info and object modification */ /* add dot "." if necessary */ /* update NIS+ passwd table */ /* nisd in temp read-only mode (nisbackup(1M)) */ "could not update NIS+ passwd: %s",
* 8 is the magic number from way back in 4.1.x. * "Password file/table busy. Try again later." /* if NIS+ update fails, bail now */ "could not update NIS+ passwd: %s",
* nothing happens here because we cannot re-encrypt the credential * because we do not have the unencrypted new password .... :^( /* NIS+ master updated; if YP-forwarding turned on, do YP */ int try = 0;
/* retry counter for YP & NIS+ updates */ * Attempt the YP passwd map update; * on failures use exponential backoff * On repeated failures (MAX_RETRY), * give up & undo NIS+ table update try = 0;
/* clear for undo attempts */ "unable to update NIS(YP) passwd \ /* set "new" passwd back to old password */ /* undo the NIS+ passwd table update */ /* exponential backoff each try */ * Update table with old passwd information, * freeing the old 'mod_res' struct first. * 'eobj' has already been set to 'ecol' above. /* On success, exit; otherwise increment ctr */ /* NIS+ update repeated failures, bail now and log */ passwd update; maybe out-of-sync with YP map -- verify by hand");
/* the epilogue just consists of freeing up data */ /* Restore column stuff so that we can free eobj/pobj */ * (void) xdr_free(xdr_result, result); * Insert additional freeing code here, if needed * (void) xdr_free(xdr_result, result); * Insert additional freeing code here, if needed