summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in2
-rw-r--r--source3/lib/smbpasswd.c201
-rw-r--r--source3/passdb/ldap.c6
-rw-r--r--source3/passdb/nispass.c5
-rw-r--r--source3/passdb/passdb.c132
-rw-r--r--source3/passdb/pdb_smbpasswd.c12
-rw-r--r--source3/passdb/smbpassfile.c2
-rw-r--r--source3/utils/pdbedit.c28
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 */