2 Unix SMB/CIFS implementation.
3 smbpasswd file format routines
5 Copyright (C) Andrew Tridgell 1992-1998
6 Modified by Jeremy Allison 1995.
7 Modified by Gerald (Jerry) Carter 2000-2001
8 Copyright (C) Tim Potter 2001
9 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
10 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2005
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 /*! \file lib/smbpasswd.c
28 The smbpasswd file is used to store encrypted passwords in a similar
29 fashion to the /etc/passwd file. The format is colon separated fields
30 with one user per line like so:
32 <username>:<uid>:<lanman hash>:<nt hash>:<acb info>:<last change time>
34 The username and uid must correspond to an entry in the /etc/passwd
35 file. The lanman and nt password hashes are 32 hex digits corresponding
36 to the 16-byte lanman and nt hashes respectively.
38 The password last change time is stored as a string of the format
39 LCD-<change time> where the change time is expressed as an
45 'U' User account (normal)
46 'M' MNS logon user account - what is this ?
47 'W' Workstation account
50 'X' No Xpiry on password
51 'I' Interdomain trust account
56 #include "system/locale.h"
57 #include "lib/samba3/samba3.h"
59 /*! Convert 32 hex characters into a 16 byte array. */
61 struct samr_Password
*smbpasswd_gethexpwd(TALLOC_CTX
*mem_ctx
, const char *p
)
64 unsigned char lonybble
, hinybble
;
65 const char *hexchars
= "0123456789ABCDEF";
67 struct samr_Password
*pwd
= talloc(mem_ctx
, struct samr_Password
);
71 for (i
= 0; i
< (sizeof(pwd
->hash
) * 2); i
+= 2)
73 hinybble
= toupper(p
[i
]);
74 lonybble
= toupper(p
[i
+ 1]);
76 p1
= strchr_m(hexchars
, hinybble
);
77 p2
= strchr_m(hexchars
, lonybble
);
83 hinybble
= PTR_DIFF(p1
, hexchars
);
84 lonybble
= PTR_DIFF(p2
, hexchars
);
86 pwd
->hash
[i
/ 2] = (hinybble
<< 4) | lonybble
;
91 /*! Convert a 16-byte array into 32 hex characters. */
92 char *smbpasswd_sethexpwd(TALLOC_CTX
*mem_ctx
, struct samr_Password
*pwd
, uint16_t acb_info
)
97 p
= talloc_array(mem_ctx
, char, 33);
102 for (i
= 0; i
< sizeof(pwd
->hash
); i
++)
103 slprintf(&p
[i
*2], 3, "%02X", pwd
->hash
[i
]);
105 if (acb_info
& ACB_PWNOTREQ
)
106 p
= talloc_strdup(mem_ctx
, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
108 p
= talloc_strdup(mem_ctx
, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
113 /*! Encode account control bits (ACBs) into a string. */
115 char *smbpasswd_encode_acb_info(TALLOC_CTX
*mem_ctx
, uint16_t acb_info
)
117 char *acct_str
= talloc_array(mem_ctx
, char, 35);
122 if (acb_info
& ACB_PWNOTREQ
) acct_str
[i
++] = 'N';
123 if (acb_info
& ACB_DISABLED
) acct_str
[i
++] = 'D';
124 if (acb_info
& ACB_HOMDIRREQ
) acct_str
[i
++] = 'H';
125 if (acb_info
& ACB_TEMPDUP
) acct_str
[i
++] = 'T';
126 if (acb_info
& ACB_NORMAL
) acct_str
[i
++] = 'U';
127 if (acb_info
& ACB_MNS
) acct_str
[i
++] = 'M';
128 if (acb_info
& ACB_WSTRUST
) acct_str
[i
++] = 'W';
129 if (acb_info
& ACB_SVRTRUST
) acct_str
[i
++] = 'S';
130 if (acb_info
& ACB_AUTOLOCK
) acct_str
[i
++] = 'L';
131 if (acb_info
& ACB_PWNOEXP
) acct_str
[i
++] = 'X';
132 if (acb_info
& ACB_DOMTRUST
) acct_str
[i
++] = 'I';
135 acct_str
[i
++] = '\0';