Transform the sequence_number operation into a normal extended operation as it should...
[Samba.git] / source4 / lib / samba3 / smbpasswd.c
blob47c826f9df2e1a8e0d87fedbae8b19f953d22bec
1 /*
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
41 'N' No password
42 'D' Disabled
43 'H' Homedir required
44 'T' Temp account.
45 'U' User account (normal)
46 'M' MNS logon user account - what is this ?
47 'W' Workstation account
48 'S' Server account
49 'L' Locked account
50 'X' No Xpiry on password
51 'I' Interdomain trust account
55 #include "includes.h"
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)
63 int i;
64 unsigned char lonybble, hinybble;
65 const char *hexchars = "0123456789ABCDEF";
66 const char *p1, *p2;
67 struct samr_Password *pwd = talloc(mem_ctx, struct samr_Password);
69 if (!p) return NULL;
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);
79 if (!p1 || !p2) {
80 return NULL;
83 hinybble = PTR_DIFF(p1, hexchars);
84 lonybble = PTR_DIFF(p2, hexchars);
86 pwd->hash[i / 2] = (hinybble << 4) | lonybble;
88 return pwd;
91 /*! Convert a 16-byte array into 32 hex characters. */
92 struct samr_Password *lm_hash_p = NULL;
93 struct samr_Password *nt_hash_p = NULL;
95 char *smbpasswd_sethexpwd(TALLOC_CTX *mem_ctx, struct samr_Password *pwd, uint16_t acb_info)
97 char *p;
98 if (pwd != NULL) {
99 int i;
100 p = talloc_array(mem_ctx, char, 33);
101 if (!p) {
102 return NULL;
105 for (i = 0; i < sizeof(pwd->hash); i++)
106 slprintf(&p[i*2], 3, "%02X", pwd->hash[i]);
107 } else {
108 if (acb_info & ACB_PWNOTREQ)
109 p = talloc_strdup(mem_ctx, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
110 else
111 p = talloc_strdup(mem_ctx, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
113 return p;
116 /*! Decode the account control bits (ACB) info from a string. */
118 uint16_t smbpasswd_decode_acb_info(const char *p)
120 uint16_t acb_info = 0;
121 bool finished = false;
124 * Check if the account type bits have been encoded after the
125 * NT password (in the form [NDHTUWSLXI]).
128 if (*p != '[') return 0;
130 for (p++; *p && !finished; p++)
132 switch (*p) {
133 case 'N': /* 'N'o password. */
134 acb_info |= ACB_PWNOTREQ;
135 break;
136 case 'D': /* 'D'isabled. */
137 acb_info |= ACB_DISABLED;
138 break;
139 case 'H': /* 'H'omedir required. */
140 acb_info |= ACB_HOMDIRREQ;
141 break;
142 case 'T': /* 'T'emp account. */
143 acb_info |= ACB_TEMPDUP;
144 break;
145 case 'U': /* 'U'ser account (normal). */
146 acb_info |= ACB_NORMAL;
147 break;
148 case 'M': /* 'M'NS logon user account. What is this ? */
149 acb_info |= ACB_MNS;
150 break;
151 case 'W': /* 'W'orkstation account. */
152 acb_info |= ACB_WSTRUST;
153 break;
154 case 'S': /* 'S'erver account. */
155 acb_info |= ACB_SVRTRUST;
156 break;
157 case 'L': /* 'L'ocked account. */
158 acb_info |= ACB_AUTOLOCK;
159 break;
160 case 'X': /* No 'X'piry on password */
161 acb_info |= ACB_PWNOEXP;
162 break;
163 case 'I': /* 'I'nterdomain trust account. */
164 acb_info |= ACB_DOMTRUST;
165 break;
167 case ' ':
168 break;
169 case ':':
170 case '\n':
171 case ']':
172 default:
173 finished = true;
174 break;
178 return acb_info;
181 /*! Encode account control bits (ACBs) into a string. */
183 char *smbpasswd_encode_acb_info(TALLOC_CTX *mem_ctx, uint16_t acb_info)
185 char *acct_str = talloc_array(mem_ctx, char, 35);
186 size_t i = 0;
188 acct_str[i++] = '[';
190 if (acb_info & ACB_PWNOTREQ ) acct_str[i++] = 'N';
191 if (acb_info & ACB_DISABLED ) acct_str[i++] = 'D';
192 if (acb_info & ACB_HOMDIRREQ) acct_str[i++] = 'H';
193 if (acb_info & ACB_TEMPDUP ) acct_str[i++] = 'T';
194 if (acb_info & ACB_NORMAL ) acct_str[i++] = 'U';
195 if (acb_info & ACB_MNS ) acct_str[i++] = 'M';
196 if (acb_info & ACB_WSTRUST ) acct_str[i++] = 'W';
197 if (acb_info & ACB_SVRTRUST ) acct_str[i++] = 'S';
198 if (acb_info & ACB_AUTOLOCK ) acct_str[i++] = 'L';
199 if (acb_info & ACB_PWNOEXP ) acct_str[i++] = 'X';
200 if (acb_info & ACB_DOMTRUST ) acct_str[i++] = 'I';
202 acct_str[i++] = ']';
203 acct_str[i++] = '\0';
205 return acct_str;