mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
65e35d5d4b
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 4a01e24030
)
202 lines
5.9 KiB
C
202 lines
5.9 KiB
C
/*
|
|
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;
|
|
}
|