diff options
author | Tim Potter <tpot@samba.org> | 2001-09-06 09:10:26 +0000 |
---|---|---|
committer | Tim Potter <tpot@samba.org> | 2001-09-06 09:10:26 +0000 |
commit | 65e35d5d4bf2a35fde52d1fb795c84764009acad (patch) | |
tree | ad42f02edccab85e0ccd49ece7e8fba347a0d6e1 /source3 | |
parent | 5661d1c82f03b2254b681e135b20991da334d27f (diff) | |
download | samba-65e35d5d4bf2a35fde52d1fb795c84764009acad.tar.gz samba-65e35d5d4bf2a35fde52d1fb795c84764009acad.tar.bz2 samba-65e35d5d4bf2a35fde52d1fb795c84764009acad.zip |
Started a cleanup of smbpasswd related stuff. I've created a new file
lib/smbpasswd.c which will contain routines related to manipulating
smbpasswd entries.
- renamed and moved pdb_{get,set}hexpwd() functions
- renamed and moved pdb_{decode,encode}acct_ctrl() functions
- started hiding references to the cruftalicious
NEW_PW_FORMAT_SPACE_PADDED_LEN constant
- started gradual rename of references to acct_ctrl to acb_info which is
the nomenclature used in MSDN and header files
There's still more work to be done. Currently there are several places
where smbpasswd entries are iterated etc. Ideally this should all happen
through the passdb system.
(This used to be commit 4a01e240305fb6fead973beef4937a016b15d744)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/Makefile.in | 2 | ||||
-rw-r--r-- | source3/lib/smbpasswd.c | 201 | ||||
-rw-r--r-- | source3/passdb/ldap.c | 6 | ||||
-rw-r--r-- | source3/passdb/nispass.c | 5 | ||||
-rw-r--r-- | source3/passdb/passdb.c | 132 | ||||
-rw-r--r-- | source3/passdb/pdb_smbpasswd.c | 12 | ||||
-rw-r--r-- | source3/passdb/smbpassfile.c | 2 | ||||
-rw-r--r-- | source3/utils/pdbedit.c | 28 |
8 files changed, 232 insertions, 156 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 71f8015cb9..bb059ba1c0 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -113,7 +113,7 @@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \ lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.o \ lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \ lib/ms_fnmatch.o lib/select.o lib/error.o lib/messages.o \ - lib/md5.o lib/hmacmd5.o lib/iconv.o \ + lib/md5.o lib/hmacmd5.o lib/iconv.o lib/smbpasswd.o \ nsswitch/wb_client.o nsswitch/wb_common.o $(TDB_OBJ) READLINE_OBJ = lib/readline.o diff --git a/source3/lib/smbpasswd.c b/source3/lib/smbpasswd.c new file mode 100644 index 0000000000..dbd12d90db --- /dev/null +++ b/source3/lib/smbpasswd.c @@ -0,0 +1,201 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + + smbpasswd file format routines + + Copyright (C) Andrew Tridgell 1992-1998 + Modified by Jeremy Allison 1995. + Modified by Gerald (Jerry) Carter 2000-2001 + Copyright (C) Tim Potter 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/*! \file lib/smbpasswd.c + + The smbpasswd file is used to store encrypted passwords in a similar + fashion to the /etc/passwd file. The format is colon separated fields + with one user per line like so: + + <username>:<uid>:<lanman hash>:<nt hash>:<acb info>:<last change time> + + The username and uid must correspond to an entry in the /etc/passwd + file. The lanman and nt password hashes are 32 hex digits corresponding + to the 16-byte lanman and nt hashes respectively. + + The password last change time is stored as a string of the format + LCD-<change time> where the change time is expressed as an + + 'N' No password + 'D' Disabled + 'H' Homedir required + 'T' Temp account. + 'U' User account (normal) + 'M' MNS logon user account - what is this ? + 'W' Workstation account + 'S' Server account + 'L' Locked account + 'X' No Xpiry on password + 'I' Interdomain trust account + +*/ + +#include "includes.h" + +/*! Convert 32 hex characters into a 16 byte array. */ + +BOOL smbpasswd_gethexpwd(char *p, unsigned char *pwd) +{ + int i; + unsigned char lonybble, hinybble; + char *hexchars = "0123456789ABCDEF"; + char *p1, *p2; + + if (!p) return (False); + + for (i = 0; i < 32; i += 2) + { + hinybble = toupper(p[i]); + lonybble = toupper(p[i + 1]); + + p1 = strchr_m(hexchars, hinybble); + p2 = strchr_m(hexchars, lonybble); + + if (!p1 || !p2) + { + return (False); + } + + hinybble = PTR_DIFF(p1, hexchars); + lonybble = PTR_DIFF(p2, hexchars); + + pwd[i / 2] = (hinybble << 4) | lonybble; + } + return (True); +} + +/*! Convert a 16-byte array into 32 hex characters. */ + +void smbpasswd_sethexpwd(fstring p, unsigned char *pwd, uint16 acb_info) +{ + if (pwd != NULL) { + int i; + for (i = 0; i < 16; i++) + slprintf(&p[i*2], 3, "%02X", pwd[i]); + } else { + if (acb_info & ACB_PWNOTREQ) + safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33); + else + safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33); + } +} + +/*! Decode the account control bits (ACB) info from a string. */ + +uint16 smbpasswd_decode_acb_info(const char *p) +{ + uint16 acb_info = 0; + BOOL finished = False; + + /* + * Check if the account type bits have been encoded after the + * NT password (in the form [NDHTUWSLXI]). + */ + + if (*p != '[') return 0; + + for (p++; *p && !finished; p++) + { + switch (*p) { + case 'N': /* 'N'o password. */ + acb_info |= ACB_PWNOTREQ; + break; + case 'D': /* 'D'isabled. */ + acb_info |= ACB_DISABLED; + break; + case 'H': /* 'H'omedir required. */ + acb_info |= ACB_HOMDIRREQ; + break; + case 'T': /* 'T'emp account. */ + acb_info |= ACB_TEMPDUP; + break; + case 'U': /* 'U'ser account (normal). */ + acb_info |= ACB_NORMAL; + break; + case 'M': /* 'M'NS logon user account. What is this ? */ + acb_info |= ACB_MNS; + break; + case 'W': /* 'W'orkstation account. */ + acb_info |= ACB_WSTRUST; + break; + case 'S': /* 'S'erver account. */ + acb_info |= ACB_SVRTRUST; + break; + case 'L': /* 'L'ocked account. */ + acb_info |= ACB_AUTOLOCK; + break; + case 'X': /* No 'X'piry on password */ + acb_info |= ACB_PWNOEXP; + break; + case 'I': /* 'I'nterdomain trust account. */ + acb_info |= ACB_DOMTRUST; + break; + + case ' ': + break; + case ':': + case '\n': + case '\0': + case ']': + default: + finished = True; + break; + } + } + + return acb_info; +} + +/*! Encode account control bits (ACBs) into a string. */ + +char *smbpasswd_encode_acb_info(uint16 acb_info) +{ + static fstring acct_str; + size_t i = 0; + + acct_str[i++] = '['; + + if (acb_info & ACB_PWNOTREQ ) acct_str[i++] = 'N'; + if (acb_info & ACB_DISABLED ) acct_str[i++] = 'D'; + if (acb_info & ACB_HOMDIRREQ) acct_str[i++] = 'H'; + if (acb_info & ACB_TEMPDUP ) acct_str[i++] = 'T'; + if (acb_info & ACB_NORMAL ) acct_str[i++] = 'U'; + if (acb_info & ACB_MNS ) acct_str[i++] = 'M'; + if (acb_info & ACB_WSTRUST ) acct_str[i++] = 'W'; + if (acb_info & ACB_SVRTRUST ) acct_str[i++] = 'S'; + if (acb_info & ACB_AUTOLOCK ) acct_str[i++] = 'L'; + if (acb_info & ACB_PWNOEXP ) acct_str[i++] = 'X'; + if (acb_info & ACB_DOMTRUST ) acct_str[i++] = 'I'; + + for ( ; i < NEW_PW_FORMAT_SPACE_PADDED_LEN - 2 ; i++ ) + acct_str[i] = ' '; + + i = NEW_PW_FORMAT_SPACE_PADDED_LEN - 2; + acct_str[i++] = ']'; + acct_str[i++] = '\0'; + + return acct_str; +} diff --git a/source3/passdb/ldap.c b/source3/passdb/ldap.c index ee99664af4..8a2befcaa8 100644 --- a/source3/passdb/ldap.c +++ b/source3/passdb/ldap.c @@ -601,7 +601,8 @@ 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, NEW_PW_FORMAT_SPACE_PADDED_LEN)); + make_a_mod(&mods, ldap_state, "userAccountControl", + smbpasswd_encode_acb_info(newpwd->acct_ctrl)); switch(flag) { @@ -733,7 +734,8 @@ static BOOL modadd_ldap21pwd_entry(struct sam_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,NEW_PW_FORMAT_SPACE_PADDED_LEN)); + make_a_mod(&mods, ldap_state, "userAccountControl", + smbpasswd_encode_acct_ctrl(newpwd->acct_ctrl)); ldap_modify_s(ldap_struct, dn, mods); diff --git a/source3/passdb/nispass.c b/source3/passdb/nispass.c index a17a29ca7a..04b3765d59 100644 --- a/source3/passdb/nispass.c +++ b/source3/passdb/nispass.c @@ -641,7 +641,8 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd) slprintf(smb_grpid, sizeof(smb_grpid)-1, "%u", newpwd->smb_grpid); slprintf(group_rid, sizeof(group_rid)-1, "0x%x", newpwd->group_rid); - safe_strcpy(acb, pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), sizeof(acb)-1); + safe_strcpy(acb, smbpasswd_encode_acct_ctrl(newpwd->acct_ctrl), + 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); @@ -805,7 +806,7 @@ static BOOL mod_nisp21pwd_entry(struct sam_passwd* pwd, BOOL override) * 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)); + fstrcpy(acb, smbpasswd_encode_acct_ctrl(pwd->acct_ctrl)); } else { /* * If using the old format and the ACB_DISABLED or diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index fae538a77d..615083ca41 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -203,138 +203,6 @@ struct sam_disp_info *pdb_sam_to_dispinfo(SAM_ACCOUNT *user) return &disp_info; } - -/********************************************************** - 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, size_t length) -{ - static fstring acct_str; - 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; -} - -/********************************************************** - Decode the account control bits from a string. - - this function breaks coding standards minimum line width of 80 chars. - reason: vertical line-up code clarity - all case statements fit into - 15 lines, which is more important. - **********************************************************/ - -uint16 pdb_decode_acct_ctrl(const char *p) -{ - uint16 acct_ctrl = 0; - BOOL finished = False; - - /* - * Check if the account type bits have been encoded after the - * NT password (in the form [NDHTUWSLXI]). - */ - - if (*p != '[') return 0; - - for (p++; *p && !finished; p++) - { - switch (*p) - { - case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ } - case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ } - 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). */ } - case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ } - case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ } - case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ } - 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 ' ': { break; } - case ':': - case '\n': - case '\0': - case ']': - default: { finished = True; } - } - } - - return acct_ctrl; -} - -/************************************************************* - Routine to set 32 hex password characters from a 16 byte array. -**************************************************************/ -void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl) -{ - if (pwd != NULL) { - int i; - for (i = 0; i < 16; i++) - slprintf(&p[i*2], 3, "%02X", pwd[i]); - } else { - if (acct_ctrl & ACB_PWNOTREQ) - safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33); - else - safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33); - } -} - -/************************************************************* - Routine to get the 32 hex characters and turn them - into a 16 byte array. -**************************************************************/ -BOOL pdb_gethexpwd(char *p, unsigned char *pwd) -{ - int i; - unsigned char lonybble, hinybble; - char *hexchars = "0123456789ABCDEF"; - char *p1, *p2; - - if (!p) return (False); - - for (i = 0; i < 32; i += 2) - { - hinybble = toupper(p[i]); - lonybble = toupper(p[i + 1]); - - p1 = strchr_m(hexchars, hinybble); - p2 = strchr_m(hexchars, lonybble); - - if (!p1 || !p2) - { - return (False); - } - - hinybble = PTR_DIFF(p1, hexchars); - lonybble = PTR_DIFF(p2, hexchars); - - pwd[i / 2] = (hinybble << 4) | lonybble; - } - return (True); -} - /******************************************************************* Group and User RID username mapping function ********************************************************************/ diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index 1ef2995d71..1d532c0d50 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -414,7 +414,7 @@ static struct smb_passwd *getsmbfilepwent(void *vp) pw_buf.smb_passwd = NULL; pw_buf.acct_ctrl |= ACB_PWNOTREQ; } else { - if (!pdb_gethexpwd((char *)p, smbpwd)) { + if (!smbpasswd_gethexpwd((char *)p, smbpwd)) { DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n")); continue; } @@ -431,7 +431,7 @@ static struct smb_passwd *getsmbfilepwent(void *vp) the lanman password. */ if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) { if (*p != '*' && *p != 'X') { - if(pdb_gethexpwd((char *)p,smbntpwd)) + if(smbpasswd_gethexpwd((char *)p,smbntpwd)) pw_buf.smb_nt_passwd = smbntpwd; } p += 33; /* Move to the first character of the line after @@ -444,7 +444,7 @@ static struct smb_passwd *getsmbfilepwent(void *vp) if (*p == '[') { unsigned char *end_p = (unsigned char *)strchr_m((char *)p, ']'); - pw_buf.acct_ctrl = pdb_decode_acct_ctrl((char*)p); + pw_buf.acct_ctrl = smbpasswd_decode_acb_info((char*)p); /* Must have some account type set. */ if(pw_buf.acct_ctrl == 0) @@ -545,8 +545,8 @@ static char *format_new_smbpasswd_entry(struct smb_passwd *newpwd) *p++ = ':'; /* 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, NEW_PW_FORMAT_SPACE_PADDED_LEN), + slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n", + smbpasswd_encode_acb_info(newpwd->acct_ctrl), (uint32)newpwd->pass_last_set_time); return new_entry; @@ -903,7 +903,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override) * 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)); + fstrcpy(encode_bits, smbpasswd_encode_acb_info(pwd->acct_ctrl)); } else { /* * If using the old format and the ACB_DISABLED or diff --git a/source3/passdb/smbpassfile.c b/source3/passdb/smbpassfile.c index 3f3e2332a0..368414ff83 100644 --- a/source3/passdb/smbpassfile.c +++ b/source3/passdb/smbpassfile.c @@ -236,7 +236,7 @@ static BOOL get_trust_account_password_from_file( unsigned char *ret_pwd, time_t * Get the hex password. */ - if (!pdb_gethexpwd((char *)linebuf, ret_pwd) || linebuf[32] != ':' || + if (!smbpasswd_gethexpwd((char *)linebuf, ret_pwd) || linebuf[32] != ':' || strncmp(&linebuf[33], "TLC-", 4)) { DEBUG(0,("get_trust_account_password: Malformed trust password file (incorrect format).\n")); #ifdef DEBUG_PASSWORD diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 1068446905..f09fd4f773 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -89,16 +89,20 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst { char lm_passwd[33]; char nt_passwd[33]; - pdb_sethexpwd(lm_passwd, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent)); - pdb_sethexpwd(nt_passwd, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent)); + smbpasswd_sethexpwd(lm_passwd, + pdb_get_lanman_passwd(sam_pwent), + pdb_get_acct_ctrl(sam_pwent)); + smbpasswd_sethexpwd(nt_passwd, + pdb_get_nt_passwd(sam_pwent), + pdb_get_acct_ctrl(sam_pwent)); - printf ("%s:%d:%s:%s:%s:LCT-%08x:\n", - pdb_get_username(sam_pwent), - pdb_get_uid(sam_pwent), - lm_passwd, - nt_passwd, - pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent),NEW_PW_FORMAT_SPACE_PADDED_LEN), - (uint32)pdb_get_pass_last_set_time(sam_pwent)); + printf("%s:%d:%s:%s:%s:LCT-%08x:\n", + pdb_get_username(sam_pwent), + pdb_get_uid(sam_pwent), + lm_passwd, + nt_passwd, + smbpasswd_encode_acb_info(pdb_get_acct_ctrl(sam_pwent)), + (uint32)pdb_get_pass_last_set_time(sam_pwent)); } else { @@ -452,7 +456,7 @@ static int import_users (char *filename) } else { - if (!pdb_gethexpwd((char *)p, smbpwd)) + if (!smbpasswd_gethexpwd((char *)p, smbpwd)) { fprintf (stderr, "Error: malformed Lanman password entry at line %d (non hex chars)\n", line); continue; @@ -466,7 +470,7 @@ static int import_users (char *filename) { if (*p != '*' && *p != 'X') { - if (pdb_gethexpwd((char *)p,smbntpwd)) + if (smbpasswd_gethexpwd((char *)p,smbntpwd)) { sam_pwent.nt_pw = smbntpwd; } @@ -480,7 +484,7 @@ static int import_users (char *filename) { unsigned char *end_p = (unsigned char *)strchr_m((char *)p, ']'); - sam_pwent.acct_ctrl = pdb_decode_acct_ctrl((char*)p); + sam_pwent.acct_ctrl = smbpasswd_decode_acb_info((char*)p); if(sam_pwent.acct_ctrl == 0) sam_pwent.acct_ctrl = ACB_NORMAL; /* Get last change time */ |