diff options
Diffstat (limited to 'source3/passdb/nispass.c')
-rw-r--r-- | source3/passdb/nispass.c | 643 |
1 files changed, 516 insertions, 127 deletions
diff --git a/source3/passdb/nispass.c b/source3/passdb/nispass.c index f554958ade..27409eca4c 100644 --- a/source3/passdb/nispass.c +++ b/source3/passdb/nispass.c @@ -19,14 +19,37 @@ * Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" + #ifdef WITH_NISPLUS -#include "includes.h" +#ifdef BROKEN_NISPLUS_INCLUDE_FILES + +/* + * The following lines are needed due to buggy include files + * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and + * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA. + * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as + * an enum in /usr/include/rpcsvc/nis.h. + */ + +#if defined(GROUP) +#undef GROUP +#endif + +#if defined(GROUP_OBJ) +#undef GROUP_OBJ +#endif + +#endif + #include <rpcsvc/nis.h> extern int DEBUGLEVEL; +extern pstring samlogon_user; +extern BOOL sam_logon_in_ssb; -static int gotalarm; +static VOLATILE SIG_ATOMIC_T gotalarm; /*************************************************************** @@ -154,9 +177,218 @@ static void get_single_attribute(nis_object *new_obj, int col, len = entry_len; } - safe_strcpy(val, len, ENTRY_VAL(new_obj, col)); + safe_strcpy(val, ENTRY_VAL(new_obj, col), len-1); } +/************************************************************************ + makes a struct sam_passwd from a NIS+ object. + ************************************************************************/ +static BOOL make_sam_from_nisp_object(struct sam_passwd *pw_buf, nis_object *obj) +{ + int uidval; + static pstring user_name; + static pstring full_name; + static pstring home_dir; + static pstring home_drive; + static pstring logon_script; + static pstring profile_path; + static pstring acct_desc; + static pstring workstations; + static pstring temp; + static unsigned char smbpwd[16]; + static unsigned char smbntpwd[16]; + + char *p; + + pdb_init_sam(pw_buf); + pw_buf->acct_ctrl = ACB_NORMAL; + + pstrcpy(user_name, ENTRY_VAL(obj, NPF_NAME)); + pw_buf->smb_name = user_name; + + uidval = atoi(ENTRY_VAL(obj, NPF_UID)); + pw_buf->smb_userid = uidval; + + /* Check the lanman password column. */ + p = (char *)ENTRY_VAL(obj, NPF_LMPWD); + if (*p == '*' || *p == 'X') { + /* Password deliberately invalid - end here. */ + DEBUG(10, ("make_sam_from_nisp_object: entry invalidated for user %s\n", user_name)); + pw_buf->smb_nt_passwd = NULL; + pw_buf->smb_passwd = NULL; + pw_buf->acct_ctrl |= ACB_DISABLED; + return True; + } + if (!strncasecmp(p, "NO PASSWORD", 11)) { + pw_buf->smb_passwd = NULL; + pw_buf->acct_ctrl |= ACB_PWNOTREQ; + } else { + if (strlen(p) != 32 || !pdb_gethexpwd(p, smbpwd)) + { + DEBUG(0, ("make_sam_from_nisp_object: malformed LM pwd entry.\n")); + return False; + } + } + + pw_buf->smb_passwd = smbpwd; + + /* Check the NT password column. */ + p = ENTRY_VAL(obj, NPF_NTPWD); + if (*p != '*' && *p != 'X') { + if (strlen(p) != 32 || !pdb_gethexpwd(p, smbntpwd)) + { + DEBUG(0, ("make_smb_from_nisp_object: malformed NT pwd entry\n")); + return False; + } + pw_buf->smb_nt_passwd = smbntpwd; + } + + p = (char *)ENTRY_VAL(obj, NPF_ACB); + if (*p == '[') + { + pw_buf->acct_ctrl = pdb_decode_acct_ctrl(p); + + /* Must have some account type set. */ + if(pw_buf->acct_ctrl == 0) + pw_buf->acct_ctrl = ACB_NORMAL; + + /* Now try and get the last change time. */ + if(*p == ']') + p++; + if(*p == ':') { + p++; + if(*p && (StrnCaseCmp(p, "LCT-", 4)==0)) { + int i; + p += 4; + for(i = 0; i < 8; i++) { + if(p[i] == '\0' || !isxdigit(p[i])) + break; + } + if(i == 8) { + /* + * p points at 8 characters of hex digits - + * read into a time_t as the seconds since + * 1970 that the password was last changed. + */ + pw_buf->pass_last_set_time = (time_t)strtol(p, NULL, 16); + } + } + } + } else { + /* 'Old' style file. Fake up based on user name. */ + /* + * Currently trust accounts are kept in the same + * password file as 'normal accounts'. If this changes + * we will have to fix this code. JRA. + */ + if(pw_buf->smb_name[strlen(pw_buf->smb_name) - 1] == '$') { + pw_buf->acct_ctrl &= ~ACB_NORMAL; + pw_buf->acct_ctrl |= ACB_WSTRUST; + } + } + + get_single_attribute(obj, NPF_SMB_GRPID, temp, sizeof(pstring)); + pw_buf->smb_grpid = atoi(temp); + + get_single_attribute(obj, NPF_USER_RID, temp, sizeof(pstring)); + pw_buf->user_rid = (strlen(temp) > 0) ? + strtol(temp, NULL, 16) : pdb_uid_to_user_rid (pw_buf->smb_userid); + + if (pw_buf->smb_name[strlen(pw_buf->smb_name)-1] != '$') { + + /* XXXX hack to get standard_sub_basic() to use sam logon username */ + /* possibly a better way would be to do a become_user() call */ + pstrcpy(samlogon_user, pw_buf->smb_name); + sam_logon_in_ssb = True; + + get_single_attribute(obj, NPF_GROUP_RID, temp, sizeof(pstring)); + pw_buf->group_rid = (strlen(temp) > 0) ? + strtol(temp, NULL, 16) : pdb_gid_to_group_rid (pw_buf->smb_grpid); + + get_single_attribute(obj, NPF_FULL_NAME, full_name, sizeof(pstring)); +#if 1 + /* It seems correct to use the global values - but in that case why + * do we want these NIS+ entries anyway ?? + */ + pstrcpy(logon_script , lp_logon_script ()); + pstrcpy(profile_path , lp_logon_path ()); + pstrcpy(home_drive , lp_logon_drive ()); + pstrcpy(home_dir , lp_logon_home ()); +#else + get_single_attribute(obj, NPF_LOGON_SCRIPT, logon_script, sizeof(pstring)); + get_single_attribute(obj, NPF_PROFILE_PATH, profile_path, sizeof(pstring)); + get_single_attribute(obj, NPF_DIR_DRIVE, home_drive, sizeof(pstring)); + get_single_attribute(obj, NPF_HOME_DIR, home_dir, sizeof(pstring)); +#endif + get_single_attribute(obj, NPF_ACCT_DESC, acct_desc, sizeof(pstring)); + get_single_attribute(obj, NPF_WORKSTATIONS, workstations, sizeof(pstring)); + + sam_logon_in_ssb = False; + + } else { + + pw_buf->group_rid = DOMAIN_GROUP_RID_USERS; /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */ + + pstrcpy(full_name , ""); + pstrcpy(logon_script , ""); + pstrcpy(profile_path , ""); + pstrcpy(home_drive , ""); + pstrcpy(home_dir , ""); + pstrcpy(acct_desc , ""); + pstrcpy(workstations , ""); + } + + pw_buf->full_name = full_name; + pw_buf->home_dir = home_dir; + pw_buf->dir_drive = home_drive; + pw_buf->logon_script = logon_script; + pw_buf->profile_path = profile_path; + pw_buf->acct_desc = acct_desc; + pw_buf->workstations = workstations; + + pw_buf->unknown_str = NULL; /* don't know, yet! */ + pw_buf->munged_dial = NULL; /* "munged" dial-back telephone number */ + + pw_buf->unknown_3 = 0xffffff; /* don't know */ + pw_buf->logon_divs = 168; /* hours per week */ + pw_buf->hours_len = 21; /* 21 times 8 bits = 168 */ + memset(pw_buf->hours, 0xff, pw_buf->hours_len); /* available at all hours */ + pw_buf->unknown_5 = 0x00020000; /* don't know */ + pw_buf->unknown_6 = 0x000004ec; /* don't know */ + + return True; +} + +/************************************************************************ + makes a struct sam_passwd from a NIS+ result. + ************************************************************************/ +static BOOL make_sam_from_nisresult(struct sam_passwd *pw_buf, nis_result *result) +{ + if (pw_buf == NULL || result == NULL) return False; + + if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND) + { + DEBUG(0, ("make_sam_from_nisresult: NIS+ lookup failure: %s\n", + nis_sperrno(result->status))); + return False; + } + + /* User not found. */ + if (NIS_RES_NUMOBJ(result) <= 0) + { + DEBUG(10, ("make_sam_from_nisresult: user not found in NIS+\n")); + return False; + } + + if (NIS_RES_NUMOBJ(result) > 1) + { + DEBUG(10, ("make_sam_from_nisresult: WARNING: Multiple entries for user in NIS+ table!\n")); + } + + /* Grab the first hit. */ + return make_sam_from_nisp_object(pw_buf, &NIS_RES_OBJECT(result)[0]); + } + /*************************************************************** calls nis_list, returns results. ****************************************************************/ @@ -205,21 +437,36 @@ static void *startnisppwent(BOOL update) ****************************************************************/ static void endnisppwent(void *vp) { + struct nisp_enum_info *res = (struct nisp_enum_info *)vp; + nis_freeresult(res->result); + DEBUG(7,("endnisppwent: freed enumeration list\n")); } /************************************************************************* Routine to return the next entry in the nisplus passwd list. - this function is a nice, messy combination of reading: - - the nisplus passwd file - - the unix password database - - nisp.conf options (not done at present). do not call this function directly. use passdb.c instead. *************************************************************************/ static struct sam_passwd *getnisp21pwent(void *vp) { - return NULL; + struct nisp_enum_info *res = (struct nisp_enum_info *)vp; + static struct sam_passwd pw_buf; + int which; + BOOL ret; + + if (res == NULL || (int)(res->enum_entry) < 0 || + (int)(res->enum_entry) > (NIS_RES_NUMOBJ(res->result) - 1)) { + ret = False; + } else { + which = (int)(res->enum_entry); + ret = make_sam_from_nisp_object(&pw_buf, + &NIS_RES_OBJECT(res->result)[which]); + if (ret && which < (NIS_RES_NUMOBJ(res->result) - 1)) + (int)(res->enum_entry)++; + } + + return ret ? &pw_buf : NULL; } /************************************************************************* @@ -231,7 +478,8 @@ static struct sam_passwd *getnisp21pwent(void *vp) *************************************************************************/ static SMB_BIG_UINT getnisppwpos(void *vp) { - return (SMB_BIG_UINT)0; + struct nisp_enum_info *res = (struct nisp_enum_info *)vp; + return (SMB_BIG_UINT)(res->enum_entry); } /************************************************************************* @@ -243,7 +491,13 @@ static SMB_BIG_UINT getnisppwpos(void *vp) *************************************************************************/ static BOOL setnisppwpos(void *vp, SMB_BIG_UINT tok) { - return False; + struct nisp_enum_info *res = (struct nisp_enum_info *)vp; + if (tok < (NIS_RES_NUMOBJ(res->result) - 1)) { + res->enum_entry = tok; + return True; + } else { + return False; + } } /************************************************************************* @@ -255,7 +509,7 @@ static void set_single_attribute(nis_object *new_obj, int col, if (new_obj == NULL) return; ENTRY_VAL(new_obj, col) = val; - ENTRY_LEN(new_obj, col) = len; + ENTRY_LEN(new_obj, col) = len+1; if (flags != 0) { @@ -295,12 +549,12 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd) fstring pwdlchg_t; fstring pwdmchg_t; - bzero(logon_t , sizeof(logon_t )); - bzero(logoff_t , sizeof(logoff_t )); - bzero(kickoff_t, sizeof(kickoff_t)); - bzero(pwdlset_t, sizeof(pwdlset_t)); - bzero(pwdlchg_t, sizeof(pwdlchg_t)); - bzero(pwdmchg_t, sizeof(pwdmchg_t)); + memset((char *)logon_t , '\0', sizeof(logon_t )); + memset((char *)logoff_t , '\0', sizeof(logoff_t )); + memset((char *)kickoff_t, '\0', sizeof(kickoff_t)); + memset((char *)pwdlset_t, '\0', sizeof(pwdlset_t)); + memset((char *)pwdlchg_t, '\0', sizeof(pwdlchg_t)); + memset((char *)pwdmchg_t, '\0', sizeof(pwdmchg_t)); pfile = lp_smb_passwd_file(); @@ -308,19 +562,17 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd) result = nisp_get_nis_list(nisname); if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND) { - DEBUG(3, ( "add_nisppwd_entry: nis_list failure: %s: %s\n", + DEBUG(3, ( "add_nis21ppwd_entry: nis_list failure: %s: %s\n", nisname, nis_sperrno(result->status))); - nis_freeresult(nis_user); nis_freeresult(result); return False; } if (result->status == NIS_SUCCESS && NIS_RES_NUMOBJ(result) > 0) { - DEBUG(3, ("add_nisppwd_entry: User already exists in NIS+ password db: %s\n", + DEBUG(3, ("add_nisp21pwd_entry: User already exists in NIS+ password db: %s\n", pfile)); nis_freeresult(result); - nis_freeresult(nis_user); return False; } @@ -328,10 +580,9 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd) /* User not found. */ if (!add_user) { - DEBUG(3, ("add_nisppwd_entry: User not found in NIS+ password db: %s\n", + DEBUG(3, ("add_nisp21pwd_entry: User not found in NIS+ password db: %s\n", pfile)); nis_freeresult(result); - nis_freeresult(nis_user); return False; } @@ -341,9 +592,8 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd) if (tblresult->status != NIS_SUCCESS) { nis_freeresult(result); - nis_freeresult(nis_user); nis_freeresult(tblresult); - DEBUG(3, ( "add_nisppwd_entry: nis_lookup failure: %s\n", + DEBUG(3, ( "add_nisp21pwd_entry: nis_lookup failure: %s\n", nis_sperrno(tblresult->status))); return False; } @@ -361,22 +611,37 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd) new_obj.zo_data.objdata_u.en_data.en_cols.en_cols_len = NIS_RES_OBJECT(tblresult)->zo_data.objdata_u.ta_data.ta_maxcol; new_obj.zo_data.objdata_u.en_data.en_cols.en_cols_val = calloc(new_obj.zo_data.objdata_u.en_data.en_cols.en_cols_len, sizeof(entry_col)); - pwdb_sethexpwd(smb_passwd , newpwd->smb_passwd , newpwd->acct_ctrl); - pwdb_sethexpwd(smb_nt_passwd, newpwd->smb_nt_passwd, newpwd->acct_ctrl); + if (new_obj.zo_data.objdata_u.en_data.en_cols.en_cols_val == NULL) + { + DEBUG(0, ("add_nisp21pwd_entry: memory allocation failure\n")); + nis_freeresult(result); + nis_freeresult(tblresult); + return False; + } + + pdb_sethexpwd(smb_passwd , newpwd->smb_passwd , newpwd->acct_ctrl); + pdb_sethexpwd(smb_nt_passwd, newpwd->smb_nt_passwd, newpwd->acct_ctrl); + + newpwd->pass_last_set_time = (time_t)time(NULL); + newpwd->logon_time = (time_t)-1; + newpwd->logoff_time = (time_t)-1; + newpwd->kickoff_time = (time_t)-1; + newpwd->pass_can_change_time = (time_t)-1; + newpwd->pass_must_change_time = (time_t)-1; - pwdb_set_logon_time (logon_t , sizeof(logon_t ), newpwd->logon_time ); - pwdb_set_logoff_time (logoff_t , sizeof(logoff_t ), newpwd->logoff_time ); - pwdb_set_kickoff_time (kickoff_t, sizeof(kickoff_t), newpwd->kickoff_time ); - pwdb_set_last_set_time (pwdlset_t, sizeof(pwdlset_t), newpwd->pass_last_set_time ); - pwdb_set_can_change_time (pwdlchg_t, sizeof(pwdlchg_t), newpwd->pass_can_change_time ); - pwdb_set_must_change_time(pwdmchg_t, sizeof(pwdmchg_t), newpwd->pass_must_change_time); + slprintf(logon_t, 13, "LNT-%08X", (uint32)newpwd->logon_time); + slprintf(logoff_t, 13, "LOT-%08X", (uint32)newpwd->logoff_time); + slprintf(kickoff_t, 13, "KOT-%08X", (uint32)newpwd->kickoff_time); + slprintf(pwdlset_t, 13, "LCT-%08X", (uint32)newpwd->pass_last_set_time); + slprintf(pwdlchg_t, 13, "CCT-%08X", (uint32)newpwd->pass_can_change_time); + slprintf(pwdmchg_t, 13, "MCT-%08X", (uint32)newpwd->pass_must_change_time); - slprintf(uid, sizeof(uid), "%u", newpwd->unix_uid); + slprintf(uid, sizeof(uid), "%u", newpwd->smb_userid); slprintf(user_rid, sizeof(user_rid), "0x%x", newpwd->user_rid); slprintf(smb_grpid, sizeof(smb_grpid), "%u", newpwd->smb_grpid); slprintf(group_rid, sizeof(group_rid), "0x%x", newpwd->group_rid); - safe_strcpy(acb, pwdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), sizeof(acb)); + safe_strcpy(acb, pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), sizeof(acb)-1); set_single_attribute(&new_obj, NPF_NAME , newpwd->smb_name , strlen(newpwd->smb_name) , 0); set_single_attribute(&new_obj, NPF_UID , uid , strlen(uid) , 0); @@ -392,6 +657,7 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd) set_single_attribute(&new_obj, NPF_PWDLSET_T , pwdlset_t , strlen(pwdlset_t) , 0); set_single_attribute(&new_obj, NPF_PWDLCHG_T , pwdlchg_t , strlen(pwdlchg_t) , 0); set_single_attribute(&new_obj, NPF_PWDMCHG_T , pwdmchg_t , strlen(pwdmchg_t) , 0); +#if 0 set_single_attribute(&new_obj, NPF_FULL_NAME , newpwd->full_name , strlen(newpwd->full_name) , 0); set_single_attribute(&new_obj, NPF_HOME_DIR , newpwd->home_dir , strlen(newpwd->home_dir) , 0); set_single_attribute(&new_obj, NPF_DIR_DRIVE , newpwd->dir_drive , strlen(newpwd->dir_drive) , 0); @@ -400,26 +666,24 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd) set_single_attribute(&new_obj, NPF_ACCT_DESC , newpwd->acct_desc , strlen(newpwd->acct_desc) , 0); set_single_attribute(&new_obj, NPF_WORKSTATIONS , newpwd->workstations , strlen(newpwd->workstations) , 0); set_single_attribute(&new_obj, NPF_HOURS , newpwd->hours , newpwd->hours_len , 0); +#endif obj = &new_obj; addresult = nis_add_entry(pfile, obj, ADD_OVERWRITE | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP); - nis_freeresult(nis_user); - if (tblresult) - { - nis_freeresult(tblresult); - } if (addresult->status != NIS_SUCCESS) { - DEBUG(3, ( "add_nisppwd_entry: NIS+ table update failed: %s\n", + DEBUG(3, ( "add_nisp21pwd_entry: NIS+ table update failed: %s\n", nisname, nis_sperrno(addresult->status))); + nis_freeresult(tblresult); nis_freeresult(addresult); nis_freeresult(result); return False; } + nis_freeresult(tblresult); nis_freeresult(addresult); nis_freeresult(result); @@ -439,73 +703,198 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd) ************************************************************************/ static BOOL mod_nisp21pwd_entry(struct sam_passwd* pwd, BOOL override) { - return False; + char *oldnislmpwd, *oldnisntpwd, *oldnisacb, *oldnislct, *user_name; + char lmpwd[33], ntpwd[33], lct[13]; + nis_result *result, *addresult; + nis_object *obj; + fstring acb; + pstring nisname; + BOOL got_pass_last_set_time, ret; + int i; + + if (!*lp_smb_passwd_file()) + { + DEBUG(0, ("mod_getnisp21pwd_entry: no SMB password file set\n")); + return False; + } + + DEBUG(10, ("mod_getnisp21pwd_entry: search by name: %s\n", pwd->smb_name)); + DEBUG(10, ("mod_getnisp21pwd_entry: using NIS+ table %s\n", lp_smb_passwd_file())); + + slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", pwd->smb_name, lp_smb_passwd_file()); + + /* Search the table. */ + gotalarm = 0; + CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); + alarm(5); + + result = nis_list(nisname, FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP, NULL, NULL); + + alarm(0); + CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL); + + if (gotalarm) + { + DEBUG(0,("mod_getnisp21pwd_entry: NIS+ lookup time out\n")); + nis_freeresult(result); + return False; + } + + if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) { + /* User not found. */ + DEBUG(0,("mod_getnisp21pwd_entry: user not found in NIS+\n")); + nis_freeresult(result); + return False; + } + + DEBUG(6,("mod_getnisp21pwd_entry: entry exists\n")); + + obj = NIS_RES_OBJECT(result); + + user_name = ENTRY_VAL(obj, NPF_NAME); + oldnislmpwd = ENTRY_VAL(obj, NPF_LMPWD); + oldnisntpwd = ENTRY_VAL(obj, NPF_NTPWD); + oldnisacb = ENTRY_VAL(obj, NPF_ACB); + oldnislct = ENTRY_VAL(obj, NPF_PWDLSET_T); + + + if (!override && (*oldnislmpwd == '*' || *oldnislmpwd == 'X' || + *oldnisntpwd == '*' || *oldnisntpwd == 'X')) { + /* Password deliberately invalid - end here. */ + DEBUG(10, ("mod_nisp21pwd_entry: entry invalidated for user %s\n", user_name)); + nis_freeresult(result); + return False; + } + + if (strlen(oldnislmpwd) != 32 || strlen(oldnisntpwd) != 32) { + DEBUG(0, ("mod_nisp21pwd_entry: malformed password entry (incorrect length)\n")); + nis_freeresult(result); + return False; + } + + + + /* + * Now check if the account info and the password last + * change time is available. + */ + + /* + * If both NT and lanman passwords are provided - reset password + * not required flag. + */ + + if(pwd->smb_passwd != NULL || pwd->smb_nt_passwd != NULL) { + /* Require password in the future (should ACB_DISABLED also be reset?) */ + pwd->acct_ctrl &= ~(ACB_PWNOTREQ); + } + + if (*oldnisacb == '[') { + + i = 0; + acb[i++] = oldnisacb[i]; + while(i < (sizeof(fstring) - 2) && (oldnisacb[i] != ']')) + acb[i] = oldnisacb[i++]; + + acb[i++] = ']'; + acb[i++] = '\0'; + + if (i == NEW_PW_FORMAT_SPACE_PADDED_LEN) { + /* + * We are using a new format, space padded + * acct ctrl field. Encode the given acct ctrl + * bits into it. + */ + fstrcpy(acb, pdb_encode_acct_ctrl(pwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN)); + } else { + /* + * If using the old format and the ACB_DISABLED or + * ACB_PWNOTREQ are set then set the lanman and NT passwords to NULL + * here as we have no space to encode the change. + */ + if(pwd->acct_ctrl & (ACB_DISABLED|ACB_PWNOTREQ)) { + pwd->smb_passwd = NULL; + pwd->smb_nt_passwd = NULL; + } + } + + /* Now do the LCT stuff. */ + if (StrnCaseCmp(oldnislct, "LCT-", 4) == 0) { + + for(i = 0; i < 8; i++) { + if(oldnislct[i+4] == '\0' || !isxdigit(oldnislct[i+4])) + break; + } + if (i == 8) { + /* + * p points at 8 characters of hex digits - + * read into a time_t as the seconds since + * 1970 that the password was last changed. + */ + got_pass_last_set_time = True; + } /* i == 8 */ + } /* StrnCaseCmp() */ + + } /* p == '[' */ + + /* Entry is correctly formed. */ + + + + /* Create the 32 byte representation of the new p16 */ + if(pwd->smb_passwd != NULL) { + for (i = 0; i < 16; i++) { + slprintf(&lmpwd[i*2], 32, "%02X", (uchar) pwd->smb_passwd[i]); + } + } else { + if(pwd->acct_ctrl & ACB_PWNOTREQ) + fstrcpy(lmpwd, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX"); + else + fstrcpy(lmpwd, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + } + + /* Add on the NT md4 hash */ + if (pwd->smb_nt_passwd != NULL) { + for (i = 0; i < 16; i++) { + slprintf(&ntpwd[i*2], 32, "%02X", (uchar) pwd->smb_nt_passwd[i]); + } + } else { + if(pwd->acct_ctrl & ACB_PWNOTREQ) + fstrcpy(ntpwd, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX"); + else + fstrcpy(ntpwd, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + } + + pwd->pass_last_set_time = time(NULL); + + if(got_pass_last_set_time) { + slprintf(lct, 12, "LCT-%08X", (uint32)pwd->pass_last_set_time); + } + + set_single_attribute(obj, NPF_LMPWD, lmpwd, strlen(lmpwd), EN_CRYPT); + set_single_attribute(obj, NPF_NTPWD, ntpwd, strlen(ntpwd), EN_CRYPT); + set_single_attribute(obj, NPF_ACB, acb, strlen(acb), 0); + set_single_attribute(obj, NPF_PWDLSET_T, lct, strlen(lct), 0); + + addresult = + nis_add_entry(lp_smb_passwd_file(), obj, + ADD_OVERWRITE | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP); + + if(addresult->status != NIS_SUCCESS) { + DEBUG(0, ("mod_nisp21pwd_entry: NIS+ table update failed: %s %s\n", nisname, nis_sperrno(addresult->status))); + nis_freeresult(addresult); + nis_freeresult(result); + return False; + } + + DEBUG(6,("mod_nisp21pwd_entry: password changed\n")); + + nis_freeresult(addresult); + nis_freeresult(result); + + return True; } -/************************************************************************ - makes a struct sam_passwd from a NIS+ result. - ************************************************************************/ -static BOOL make_sam_from_nisp(struct sam_passwd *pw_buf, nis_result *result) -{ - int uidval; - static pstring user_name; - static unsigned char smbpwd[16]; - static unsigned char smbntpwd[16]; - nis_object *obj; - uchar *p; - - if (pw_buf == NULL || result == NULL) return False; - - pwdb_init_sam(pw_buf); - - if (result->status != NIS_SUCCESS) - { - DEBUG(0, ("make_smb_from_nisp: NIS+ lookup failure: %s\n", - nis_sperrno(result->status))); - return False; - } - - /* User not found. */ - if (NIS_RES_NUMOBJ(result) <= 0) - { - DEBUG(10, ("make_smb_from_nisp: user not found in NIS+\n")); - return False; - } - - if (NIS_RES_NUMOBJ(result) > 1) - { - DEBUG(10, ("make_smb_from_nisp: WARNING: Multiple entries for user in NIS+ table!\n")); - } - - /* Grab the first hit. */ - obj = &NIS_RES_OBJECT(result)[0]; - - /* Check the lanman password column. */ - p = (uchar *)ENTRY_VAL(obj, NPF_LMPWD); - if (strlen((char *)p) != 32 || !pwdb_gethexpwd((char *)p, (char *)smbpwd)) - { - DEBUG(0, ("make_smb_from_nisp: malformed LM pwd entry.\n")); - return False; - } - - /* Check the NT password column. */ - p = (uchar *)ENTRY_VAL(obj, NPF_NTPWD); - if (strlen((char *)p) != 32 || !pwdb_gethexpwd((char *)p, (char *)smbntpwd)) - { - DEBUG(0, ("make_smb_from_nisp: malformed NT pwd entry\n")); - return False; - } - - strncpy(user_name, ENTRY_VAL(obj, NPF_NAME), sizeof(user_name)); - uidval = atoi(ENTRY_VAL(obj, NPF_UID)); - - pw_buf->smb_name = user_name; - pw_buf->unix_uid = uidval; - pw_buf->smb_passwd = smbpwd; - pw_buf->smb_nt_passwd = smbntpwd; - - return True; -} /************************************************************************* Routine to search the nisplus passwd file for an entry matching the username @@ -524,8 +913,8 @@ static struct sam_passwd *getnisp21pwnam(char *name) return NULL; } - DEBUG(10, ("getnisppwnam: search by name: %s\n", name)); - DEBUG(10, ("getnisppwnam: using NIS+ table %s\n", lp_smb_passwd_file())); + DEBUG(10, ("getnisp21pwnam: search by name: %s\n", name)); + DEBUG(10, ("getnisp21pwnam: using NIS+ table %s\n", lp_smb_passwd_file())); slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", name, lp_smb_passwd_file()); @@ -541,12 +930,12 @@ static struct sam_passwd *getnisp21pwnam(char *name) if (gotalarm) { - DEBUG(0,("getnisppwnam: NIS+ lookup time out\n")); + DEBUG(0,("getnisp21pwnam: NIS+ lookup time out\n")); nis_freeresult(result); return NULL; } - ret = make_sam_from_nisp(&pw_buf, result); + ret = make_sam_from_nisresult(&pw_buf, result); nis_freeresult(result); return ret ? &pw_buf : NULL; @@ -565,7 +954,7 @@ static struct sam_passwd *getnisp21pwrid(uint32 rid) if (!*lp_smb_passwd_file()) { - DEBUG(0, ("No SMB password file set\n")); + DEBUG(0, ("getnisp21pwrid: no SMB password file set\n")); return NULL; } @@ -591,7 +980,7 @@ static struct sam_passwd *getnisp21pwrid(uint32 rid) return NULL; } - ret = make_sam_from_nisp(&pw_buf, result); + ret = make_sam_from_nisresult(&pw_buf, result); nis_freeresult(result); return ret ? &pw_buf : NULL; @@ -603,52 +992,52 @@ static struct sam_passwd *getnisp21pwrid(uint32 rid) static struct smb_passwd *getnisppwent(void *vp) { - return pwdb_sam_to_smb(getnisp21pwent(vp)); + return pdb_sam_to_smb(getnisp21pwent(vp)); } static BOOL add_nisppwd_entry(struct smb_passwd *newpwd) { - return add_nisp21pwd_entry(pwdb_smb_to_sam(newpwd)); + return add_nisp21pwd_entry(pdb_smb_to_sam(newpwd)); } static BOOL mod_nisppwd_entry(struct smb_passwd* pwd, BOOL override) { - return mod_nisp21pwd_entry(pwdb_smb_to_sam(pwd), override); + return mod_nisp21pwd_entry(pdb_smb_to_sam(pwd), override); } static struct smb_passwd *getnisppwnam(char *name) { - return pwdb_sam_to_smb(getnisp21pwnam(name)); + return pdb_sam_to_smb(getnisp21pwnam(name)); } -static struct sam_passwd *getnisp21pwuid(uid_t unix_uid) +static struct sam_passwd *getnisp21pwuid(uid_t smb_userid) { - return getnisp21pwrid(pwdb_uid_to_user_rid(unix_uid)); + return getnisp21pwrid(pdb_uid_to_user_rid(smb_userid)); } -static struct smb_passwd *getnisppwrid(uid_t user_rid) +static struct smb_passwd *getnisppwrid(uint32 user_rid) { - return pwdb_sam_to_smb(getnisp21pwuid(pwdb_user_rid_to_uid(user_rid))); + return pdb_sam_to_smb(getnisp21pwuid(pdb_user_rid_to_uid(user_rid))); } -static struct smb_passwd *getnisppwuid(uid_t unix_uid) +static struct smb_passwd *getnisppwuid(uid_t smb_userid) { - return pwdb_sam_to_smb(getnisp21pwuid(unix_uid)); + return pdb_sam_to_smb(getnisp21pwuid(smb_userid)); } static struct sam_disp_info *getnispdispnam(char *name) { - return pwdb_sam_to_dispinfo(getnisp21pwnam(name)); + return pdb_sam_to_dispinfo(getnisp21pwnam(name)); } static struct sam_disp_info *getnispdisprid(uint32 rid) { - return pwdb_sam_to_dispinfo(getnisp21pwrid(rid)); + return pdb_sam_to_dispinfo(getnisp21pwrid(rid)); } static struct sam_disp_info *getnispdispent(void *vp) { - return pwdb_sam_to_dispinfo(getnisp21pwent(vp)); + return pdb_sam_to_dispinfo(getnisp21pwent(vp)); } static struct passdb_ops nispasswd_ops = { @@ -673,7 +1062,7 @@ static struct passdb_ops nispasswd_ops = { getnispdispent }; -struct passdb_ops *nisplus_initialise_password_db(void) +struct passdb_ops *nisplus_initialize_password_db(void) { return &nispasswd_ops; } @@ -693,7 +1082,7 @@ static void useful_code(void) { if (nis_user->status != NIS_SUCCESS || NIS_RES_NUMOBJ(nis_user) <= 0) { - DEBUG(3, ("add_nisppwd_entry: Unable to get NIS+ passwd entry for user: %s.\n", + DEBUG(3, ("useful_code: Unable to get NIS+ passwd entry for user: %s.\n", nis_sperrno(nis_user->status))); return False; } |