iteration of sam passwd entries was an order n-cubed algorithm due
[samba.git] / source / passdb / sampass.c
1 /*
2  * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
3  * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
4  * 
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License as published by the Free
7  * Software Foundation; either version 2 of the License, or (at your option)
8  * any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  * 
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc., 675
17  * Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 #include "includes.h"
21
22 #ifdef USE_SMBPASS_DB
23
24 extern int DEBUGLEVEL;
25 extern pstring samlogon_user;
26 extern BOOL sam_logon_in_ssb;
27
28 extern DOM_SID global_sam_sid;
29
30 /***************************************************************
31  Start to enumerate the smbpasswd list. Returns a void pointer
32  to ensure no modification outside this module.
33 ****************************************************************/
34
35 static void *startsamfilepwent(BOOL update)
36 {
37         return startsmbpwent(update);
38 }
39
40 /***************************************************************
41  End enumeration of the smbpasswd list.
42 ****************************************************************/
43
44 static void endsamfilepwent(void *vp)
45 {
46         endsmbpwent(vp);
47 }
48
49 /*************************************************************************
50  Return the current position in the smbpasswd list as an SMB_BIG_UINT.
51  This must be treated as an opaque token.
52 *************************************************************************/
53
54 static SMB_BIG_UINT getsamfilepwpos(void *vp)
55 {
56         return getsmbpwpos(vp);
57 }
58
59 /*************************************************************************
60  Set the current position in the smbpasswd list from an SMB_BIG_UINT.
61  This must be treated as an opaque token.
62 *************************************************************************/
63
64 static BOOL setsamfilepwpos(void *vp, SMB_BIG_UINT tok)
65 {
66         return setsmbpwpos(vp, tok);
67 }
68
69 /*************************************************************************
70  Routine to return the next entry in the smbpasswd list.
71  this function is a nice, messy combination of reading:
72  - the smbpasswd file
73  - the unix password database
74  - smb.conf options (not done at present).
75  *************************************************************************/
76
77 static struct sam_passwd *getsamfile21pwent(void *vp)
78 {
79         struct sam_passwd *user;
80
81         static pstring full_name;
82         static pstring home_dir;
83         static pstring home_drive;
84         static pstring logon_script;
85         static pstring profile_path;
86         static pstring acct_desc;
87         static pstring workstations;
88
89         DEBUG(5,("getsamfile21pwent\n"));
90
91         user = pwdb_smb_to_sam(getsmbfilepwent(vp));
92         if (user == NULL)
93         {
94                 return NULL;
95         }
96
97         /*
98          * get all the other gubbins we need.  substitute unix name for %U
99          * as putting the nt name in is a bit meaningless.
100          */
101
102         pstrcpy(samlogon_user, user->unix_name);
103
104         if (samlogon_user[strlen(samlogon_user)-1] == '$' && 
105             user->group_rid != DOMAIN_GROUP_RID_USERS)
106         {
107                 DEBUG(0,("trust account %s should be in DOMAIN_GROUP_RID_USERS\n",
108                           samlogon_user));
109         }
110
111         /* XXXX hack to get standard_sub_basic() to use sam logon username */
112         /* possibly a better way would be to do a become_user() call */
113         sam_logon_in_ssb = True;
114
115         pstrcpy(full_name    , "");
116         pstrcpy(logon_script , lp_logon_script       ());
117         pstrcpy(profile_path , lp_logon_path         ());
118         pstrcpy(home_drive   , lp_logon_drive        ());
119         pstrcpy(home_dir     , lp_logon_home         ());
120         pstrcpy(acct_desc    , "");
121         pstrcpy(workstations , "");
122
123         sam_logon_in_ssb = False;
124
125         user->full_name    = full_name;
126         user->home_dir     = home_dir;
127         user->dir_drive    = home_drive;
128         user->logon_script = logon_script;
129         user->profile_path = profile_path;
130         user->acct_desc    = acct_desc;
131         user->workstations = workstations;
132
133         user->unknown_str = NULL; /* don't know, yet! */
134         user->munged_dial = NULL; /* "munged" dial-back telephone number */
135
136         user->unknown_3 = 0xffffff; /* don't know */
137         user->logon_divs = 168; /* hours per week */
138         user->hours_len = 21; /* 21 times 8 bits = 168 */
139         memset(user->hours, 0xff, user->hours_len); /* available at all hours */
140         user->unknown_5 = 0x00020000; /* don't know */
141         user->unknown_6 = 0x000004ec; /* don't know */
142
143         return user;
144 }
145
146 /************************************************************************
147 search sam db by uid.
148 *************************************************************************/
149 static struct sam_passwd *getsamfilepwuid(uid_t uid)
150 {
151         struct sam_passwd *pwd = NULL;
152         void *fp = NULL;
153
154         DEBUG(10, ("search by uid: %x\n", (int)uid));
155
156         /* Open the smb password file - not for update. */
157         fp = startsam21pwent(False);
158
159         if (fp == NULL)
160         {
161                 DEBUG(0, ("unable to open sam password database.\n"));
162                 return NULL;
163         }
164
165         while ((pwd = getsamfile21pwent(fp)) != NULL && pwd->unix_uid != uid)
166         {
167         }
168
169         if (pwd != NULL)
170         {
171                 DEBUG(10, ("found by unix_uid: %x\n", (int)uid));
172         }
173
174         endsam21pwent(fp);
175
176         return pwd;
177 }
178
179 /************************************************************************
180 search sam db by rid.
181 *************************************************************************/
182 static struct sam_passwd *getsamfilepwrid(uint32 user_rid)
183 {
184         DOM_NAME_MAP gmep;
185         DOM_SID sid;
186         sid_copy(&sid, &global_sam_sid);
187         sid_append_rid(&sid, user_rid);
188
189         if (!lookupsmbpwsid(&sid, &gmep))
190         {
191                 return NULL;
192         }
193
194         return getsamfilepwuid((uid_t)gmep.unix_id);
195 }
196
197 /************************************************************************
198 search sam db by nt name.
199 *************************************************************************/
200 static struct sam_passwd *getsamfilepwntnam(const char *nt_name)
201 {
202         DOM_NAME_MAP gmep;
203
204         if (!lookupsmbpwntnam(nt_name, &gmep))
205         {
206                 return NULL;
207         }
208
209         return getsamfilepwuid((uid_t)gmep.unix_id);
210 }
211
212 /*
213  * Stub functions - implemented in terms of others.
214  */
215
216 static BOOL mod_samfile21pwd_entry(struct sam_passwd* pwd, BOOL override)
217 {
218         return mod_smbpwd_entry(pwdb_sam_to_smb(pwd), override);
219 }
220
221 static BOOL add_samfile21pwd_entry(struct sam_passwd *newpwd)
222 {
223         return add_smbpwd_entry(pwdb_sam_to_smb(newpwd));
224 }
225
226 static struct sam_disp_info *getsamfiledispntnam(const char *ntname)
227 {
228         return pwdb_sam_to_dispinfo(getsam21pwntnam(ntname));
229 }
230
231 static struct sam_disp_info *getsamfiledisprid(uint32 rid)
232 {
233         return pwdb_sam_to_dispinfo(getsam21pwrid(rid));
234 }
235
236 static struct sam_disp_info *getsamfiledispent(void *vp)
237 {
238         return pwdb_sam_to_dispinfo(getsam21pwent(vp));
239 }
240
241 static struct sam_passdb_ops sam_file_ops =
242 {
243         startsamfilepwent,
244         endsamfilepwent,
245         getsamfilepwpos,
246         setsamfilepwpos,
247         getsamfilepwntnam,
248         getsamfilepwuid,
249         getsamfilepwrid, 
250         getsamfile21pwent,
251         add_samfile21pwd_entry,
252         mod_samfile21pwd_entry,
253         getsamfiledispntnam,
254         getsamfiledisprid,
255         getsamfiledispent
256 };
257
258 struct sam_passdb_ops *file_initialise_sam_password_db(void)
259 {    
260   return &sam_file_ops;
261 }
262
263 #else
264  /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
265  void sampass_dummy_function(void) { } /* stop some compilers complaining */
266 #endif /* USE_SMBPASS_DB */