Fix scripts to generate correct tables for compilers which have character constants...
[Samba/gebeck_regimport.git] / source3 / lib / smbpasswd.c
blob92ae1ffea26a3d282fb34da7290bb8b3fff544ae
1 /*
2 Unix SMB/CIFS implementation.
4 smbpasswd file format routines
6 Copyright (C) Andrew Tridgell 1992-1998
7 Modified by Jeremy Allison 1995.
8 Modified by Gerald (Jerry) Carter 2000-2001
9 Copyright (C) Tim Potter 2001
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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"
57 /*! Convert 32 hex characters into a 16 byte array. */
59 BOOL smbpasswd_gethexpwd(char *p, unsigned char *pwd)
61 int i;
62 unsigned char lonybble, hinybble;
63 const char *hexchars = "0123456789ABCDEF";
64 char *p1, *p2;
66 if (!p) return (False);
68 for (i = 0; i < 32; i += 2)
70 hinybble = toupper(p[i]);
71 lonybble = toupper(p[i + 1]);
73 p1 = strchr_m(hexchars, hinybble);
74 p2 = strchr_m(hexchars, lonybble);
76 if (!p1 || !p2)
78 return (False);
81 hinybble = PTR_DIFF(p1, hexchars);
82 lonybble = PTR_DIFF(p2, hexchars);
84 pwd[i / 2] = (hinybble << 4) | lonybble;
86 return (True);
89 /*! Convert a 16-byte array into 32 hex characters. */
91 void smbpasswd_sethexpwd(fstring p, unsigned char *pwd, uint16 acb_info)
93 if (pwd != NULL) {
94 int i;
95 for (i = 0; i < 16; i++)
96 slprintf(&p[i*2], 3, "%02X", pwd[i]);
97 } else {
98 if (acb_info & ACB_PWNOTREQ)
99 safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
100 else
101 safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
105 /*! Decode the account control bits (ACB) info from a string. */
107 uint16 smbpasswd_decode_acb_info(const char *p)
109 uint16 acb_info = 0;
110 BOOL finished = False;
113 * Check if the account type bits have been encoded after the
114 * NT password (in the form [NDHTUWSLXI]).
117 if (*p != '[') return 0;
119 for (p++; *p && !finished; p++)
121 switch (*p) {
122 case 'N': /* 'N'o password. */
123 acb_info |= ACB_PWNOTREQ;
124 break;
125 case 'D': /* 'D'isabled. */
126 acb_info |= ACB_DISABLED;
127 break;
128 case 'H': /* 'H'omedir required. */
129 acb_info |= ACB_HOMDIRREQ;
130 break;
131 case 'T': /* 'T'emp account. */
132 acb_info |= ACB_TEMPDUP;
133 break;
134 case 'U': /* 'U'ser account (normal). */
135 acb_info |= ACB_NORMAL;
136 break;
137 case 'M': /* 'M'NS logon user account. What is this ? */
138 acb_info |= ACB_MNS;
139 break;
140 case 'W': /* 'W'orkstation account. */
141 acb_info |= ACB_WSTRUST;
142 break;
143 case 'S': /* 'S'erver account. */
144 acb_info |= ACB_SVRTRUST;
145 break;
146 case 'L': /* 'L'ocked account. */
147 acb_info |= ACB_AUTOLOCK;
148 break;
149 case 'X': /* No 'X'piry on password */
150 acb_info |= ACB_PWNOEXP;
151 break;
152 case 'I': /* 'I'nterdomain trust account. */
153 acb_info |= ACB_DOMTRUST;
154 break;
156 case ' ':
157 break;
158 case ':':
159 case '\n':
160 case '\0':
161 case ']':
162 default:
163 finished = True;
164 break;
168 return acb_info;
171 /*! Encode account control bits (ACBs) into a string. */
173 char *smbpasswd_encode_acb_info(uint16 acb_info)
175 static fstring acct_str;
176 size_t i = 0;
178 acct_str[i++] = '[';
180 if (acb_info & ACB_PWNOTREQ ) acct_str[i++] = 'N';
181 if (acb_info & ACB_DISABLED ) acct_str[i++] = 'D';
182 if (acb_info & ACB_HOMDIRREQ) acct_str[i++] = 'H';
183 if (acb_info & ACB_TEMPDUP ) acct_str[i++] = 'T';
184 if (acb_info & ACB_NORMAL ) acct_str[i++] = 'U';
185 if (acb_info & ACB_MNS ) acct_str[i++] = 'M';
186 if (acb_info & ACB_WSTRUST ) acct_str[i++] = 'W';
187 if (acb_info & ACB_SVRTRUST ) acct_str[i++] = 'S';
188 if (acb_info & ACB_AUTOLOCK ) acct_str[i++] = 'L';
189 if (acb_info & ACB_PWNOEXP ) acct_str[i++] = 'X';
190 if (acb_info & ACB_DOMTRUST ) acct_str[i++] = 'I';
192 for ( ; i < NEW_PW_FORMAT_SPACE_PADDED_LEN - 2 ; i++ )
193 acct_str[i] = ' ';
195 i = NEW_PW_FORMAT_SPACE_PADDED_LEN - 2;
196 acct_str[i++] = ']';
197 acct_str[i++] = '\0';
199 return acct_str;