diff options
Diffstat (limited to 'source3/passdb')
-rw-r--r-- | source3/passdb/ldap.c | 2 | ||||
-rw-r--r-- | source3/passdb/nispass.c | 2 | ||||
-rw-r--r-- | source3/passdb/passdb.c | 52 | ||||
-rw-r--r-- | source3/passdb/smbpass.c | 124 |
4 files changed, 109 insertions, 71 deletions
diff --git a/source3/passdb/ldap.c b/source3/passdb/ldap.c index e27b4fbea7..80ba6be3a7 100644 --- a/source3/passdb/ldap.c +++ b/source3/passdb/ldap.c @@ -576,7 +576,7 @@ static BOOL modadd_ldappwd_entry(struct smb_passwd *newpwd, int flag) make_a_mod(&mods, ldap_state, "rid", rid); make_a_mod(&mods, ldap_state, "pwdLastSet", lst); - make_a_mod(&mods, ldap_state, "userAccountControl", pdb_encode_acct_ctrl(newpwd->acct_ctrl)); + make_a_mod(&mods, ldap_state, "userAccountControl", pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN)); switch(flag) { diff --git a/source3/passdb/nispass.c b/source3/passdb/nispass.c index 04c1c23b2e..4a2a7723d6 100644 --- a/source3/passdb/nispass.c +++ b/source3/passdb/nispass.c @@ -376,7 +376,7 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd) slprintf(smb_grpid, sizeof(smb_grpid), "%u", newpwd->smb_grpid); slprintf(group_rid, sizeof(group_rid), "0x%x", newpwd->group_rid); - safe_strcpy(acb, pdb_encode_acct_ctrl(newpwd->acct_ctrl), sizeof(acb)); + safe_strcpy(acb, pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), sizeof(acb)); 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); diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 02f30b24c8..6633088245 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -491,26 +491,35 @@ struct smb_passwd *pdb_sam_to_smb(struct sam_passwd *user) /********************************************************** Encode the account control bits into a string. + length = length of string to encode into (including terminating + null). length *MUST BE MORE THAN 2* ! **********************************************************/ -char *pdb_encode_acct_ctrl(uint16 acct_ctrl) + +char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length) { static fstring acct_str; - char *p = acct_str; - - *p++ = '['; - - if (acct_ctrl & ACB_HOMDIRREQ) *p++ = 'H'; - if (acct_ctrl & ACB_TEMPDUP ) *p++ = 'T'; - if (acct_ctrl & ACB_NORMAL ) *p++ = 'U'; - if (acct_ctrl & ACB_MNS ) *p++ = 'M'; - if (acct_ctrl & ACB_WSTRUST ) *p++ = 'W'; - if (acct_ctrl & ACB_SVRTRUST ) *p++ = 'S'; - if (acct_ctrl & ACB_AUTOLOCK ) *p++ = 'L'; - if (acct_ctrl & ACB_PWNOEXP ) *p++ = 'X'; - if (acct_ctrl & ACB_DOMTRUST ) *p++ = 'I'; - - *p++ = ']'; - *p = '\0'; + size_t i = 0; + + acct_str[i++] = '['; + + if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N'; + if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D'; + if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H'; + if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T'; + if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U'; + if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M'; + if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W'; + if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S'; + if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L'; + if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X'; + if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I'; + + for ( ; i < length - 2 ; i++ ) { acct_str[i] = ' '; } + + i = length - 2; + acct_str[i++] = ']'; + acct_str[i++] = '\0'; + return acct_str; } @@ -538,15 +547,8 @@ uint16 pdb_decode_acct_ctrl(char *p) { switch (*p) { -#if 0 - /* - * Hmmm. Don't allow these to be set/read independently - * of the actual password fields. We don't want a mismatch. - * JRA. - */ case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ } case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ } -#endif case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ } case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ } case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ } @@ -556,7 +558,7 @@ uint16 pdb_decode_acct_ctrl(char *p) case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ } case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ } case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ } - + case ' ': case ':': case '\n': case '\0': diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c index a2b648b2fd..cff049dcd5 100644 --- a/source3/passdb/smbpass.c +++ b/source3/passdb/smbpass.c @@ -264,7 +264,7 @@ static struct smb_passwd *getsmbfilepwent(void *vp) p++; if(*p == ':') { p++; - if(*p && StrnCaseCmp((char *)p, "LCT-", 4)) { + if(*p && (StrnCaseCmp((char *)p, "LCT-", 4)==0)) { int i; p += 4; for(i = 0; i < 8; i++) { @@ -473,7 +473,7 @@ Error was %s\n", newpwd->smb_name, pfile, strerror(errno))); return False; } - new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + 5 + 1 + 13 + 2; + new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2; if((new_entry = (char *)malloc( new_entry_length )) == NULL) { DEBUG(0, ("add_smbfilepwd_entry(malloc): Failed to add entry for user %s to file %s. \ @@ -518,8 +518,7 @@ Error was %s\n", newpwd->smb_name, pfile, strerror(errno))); /* Add the account encoding and the last change time. */ slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n", - pdb_encode_acct_ctrl(newpwd->acct_ctrl), - (uint32)time(NULL)); + pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), (uint32)time(NULL)); #ifdef DEBUG_PASSWORD DEBUG(100, ("add_smbfilepwd_entry(%d): new_entry_len %d entry_len %d made line |%s|", @@ -538,9 +537,11 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n", } endsmbfilepwent(fp); + free(new_entry); return False; } + free(new_entry); endsmbfilepwent(fp); return True; } @@ -654,7 +655,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override) * * or, * - * username:uid:[32hex bytes]:[32hex bytes]:....ignored.... + * username:uid:[32hex bytes]:[32hex bytes]:[attributes]:LCT-XXXXXXXX:...ignored. * * if Windows NT compatible passwords are also present. */ @@ -772,11 +773,31 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override) if (*p == '[') { i = 0; - p++; + encode_bits[i++] = *p++; while((linebuf_len > PTR_DIFF(p, linebuf)) && (*p != ']')) encode_bits[i++] = *p++; - encode_bits[i] = '\0'; + encode_bits[i++] = ']'; + encode_bits[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(encode_bits, 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; + } + } /* Go past the ']' */ if(linebuf_len > PTR_DIFF(p, linebuf)) @@ -785,8 +806,8 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override) if((linebuf_len > PTR_DIFF(p, linebuf)) && (*p == ':')) { p++; - /* We should be pointing at the TLC entry. */ - if((linebuf_len > (PTR_DIFF(p, linebuf) + 13)) && StrnCaseCmp((char *)p, "LCT-", 4)) { + /* We should be pointing at the LCT entry. */ + if((linebuf_len > (PTR_DIFF(p, linebuf) + 13)) && (StrnCaseCmp((char *)p, "LCT-", 4) == 0)) { p += 4; for(i = 0; i < 8; i++) { @@ -807,39 +828,6 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override) /* Entry is correctly formed. */ - /* - * Do an atomic write into the file at the position defined by - * seekpos. - */ - - /* The mod user write needs to be atomic - so get the fd from - the fp and do a raw write() call. - */ - - fd = fileno(fp); - - if (sys_lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) { - DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile)); - pw_file_unlock(lockfd,&pw_file_lock_depth); - fclose(fp); - return False; - } - - /* Sanity check - ensure the character is a ':' */ - if (read(fd, &c, 1) != 1) { - DEBUG(0, ("mod_smbfilepwd_entry: read fail on file %s.\n", pfile)); - pw_file_unlock(lockfd,&pw_file_lock_depth); - fclose(fp); - return False; - } - - if (c != ':') { - DEBUG(0, ("mod_smbfilepwd_entry: check on passwd file %s failed.\n", pfile)); - pw_file_unlock(lockfd,&pw_file_lock_depth); - fclose(fp); - return False; - } - /* Create the 32 byte representation of the new p16 */ if(pwd->smb_passwd != NULL) { for (i = 0; i < 16; i++) { @@ -854,7 +842,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override) /* Add on the NT md4 hash */ ascii_p16[32] = ':'; - wr_len = 65; + wr_len = 66; if (pwd->smb_nt_passwd != NULL) { for (i = 0; i < 16; i++) { slprintf(&ascii_p16[(i*2)+33], sizeof(fstring) - 1, "%02X", (uchar) pwd->smb_nt_passwd[i]); @@ -865,6 +853,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override) else fstrcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); } + ascii_p16[65] = ':'; /* Add on the account info bits and the time of last password change. */ @@ -874,7 +863,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override) if(got_pass_last_set_time) { slprintf(&ascii_p16[strlen(ascii_p16)], sizeof(ascii_p16)-(strlen(ascii_p16)+1), - ":[%s]:TLC-%08X:", + "%s:LCT-%08X:", encode_bits, (uint32)pwd->pass_last_set_time ); wr_len = strlen(ascii_p16); } @@ -884,6 +873,53 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override) dump_data(100, ascii_p16, wr_len); #endif + if(wr_len > sizeof(linebuf)) { + DEBUG(0, ("mod_smbfilepwd_entry: line to write (%d) is too long.\n", wr_len+1)); + pw_file_unlock(lockfd,&pw_file_lock_depth); + fclose(fp); + return (False); + } + + /* + * Do an atomic write into the file at the position defined by + * seekpos. + */ + + /* The mod user write needs to be atomic - so get the fd from + the fp and do a raw write() call. + */ + + fd = fileno(fp); + + if (sys_lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) { + DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile)); + pw_file_unlock(lockfd,&pw_file_lock_depth); + fclose(fp); + return False; + } + + /* Sanity check - ensure the areas we are writing are framed by ':' */ + if (read(fd, linebuf, wr_len+1) != wr_len+1) { + DEBUG(0, ("mod_smbfilepwd_entry: read fail on file %s.\n", pfile)); + pw_file_unlock(lockfd,&pw_file_lock_depth); + fclose(fp); + return False; + } + + if ((linebuf[0] != ':') || (linebuf[wr_len] != ':')) { + DEBUG(0, ("mod_smbfilepwd_entry: check on passwd file %s failed.\n", pfile)); + pw_file_unlock(lockfd,&pw_file_lock_depth); + fclose(fp); + return False; + } + + if (sys_lseek(fd, pwd_seekpos, SEEK_SET) != pwd_seekpos) { + DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile)); + pw_file_unlock(lockfd,&pw_file_lock_depth); + fclose(fp); + return False; + } + if (write(fd, ascii_p16, wr_len) != wr_len) { DEBUG(0, ("mod_smbfilepwd_entry: write failed in passwd file %s\n", pfile)); pw_file_unlock(lockfd,&pw_file_lock_depth); |