preparing for release of alpha.2.5
[Samba.git] / source / passdb / sampassnt5ldap.c
blob6d8586a2924b7db84ccbb07c0fb1863a9fb4d972
2 /*
3 Unix SMB/Netbios implementation.
4 Version 2.0.
5 LDAP protocol helper functions for SAMBA
6 Copyright (C) Matthew Chapman 1998
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "includes.h"
26 #ifdef WITH_NT5LDAP
28 #include <lber.h>
29 #include <ldap.h>
30 #include "ldapdb.h"
32 extern int DEBUGLEVEL;
33 extern DOM_SID global_sam_sid;
35 /*******************************************************************
36 NT name/RID search functions.
37 ******************************************************************/
39 /*******************************************************************
40 Contruct a sam_passwd structure.
41 ******************************************************************/
43 struct sam_passwd *
44 nt5ldapsam_getent (LDAPDB * hds)
46 static pstring full_name;
47 static pstring acct_desc;
48 static pstring home_dir;
49 static pstring home_drive;
50 static pstring logon_script;
51 static pstring profile_path;
52 static pstring workstations;
53 struct sam_passwd *sam21;
54 struct smb_passwd *smbpw;
55 struct berval *bv;
56 pstring temp;
58 extern BOOL sam_logon_in_ssb;
59 extern pstring samlogon_user;
61 if (!ldapdb_peek (hds))
63 return NULL;
66 smbpw = nt5ldapsmb_getent (hds);
67 if (smbpw == NULL)
69 return NULL;
72 sam21 = pwdb_smb_to_sam (smbpw);
74 /* uid/mSSFUName from smbpw */
76 /* sAMAccountName from smbpw */
78 if (ldapdb_get_pvalue (hds, "displayName", full_name) ||
79 ldapdb_get_pvalue (hds, "cn", full_name))
80 sam21->full_name = full_name;
82 /* XXX rfc2307 conflict */
83 if (ldapdb_get_pvalue (hds, "homeDirectory", home_dir))
84 sam21->home_dir = home_dir;
86 if (ldapdb_get_pvalue (hds, "homeDrive", home_drive))
87 sam21->dir_drive = home_drive;
89 if (ldapdb_get_pvalue (hds, "scriptPath", logon_script))
90 sam21->logon_script = logon_script;
92 if (ldapdb_get_pvalue (hds, "profilePath", profile_path))
93 sam21->profile_path = profile_path;
95 if (ldapdb_get_pvalue (hds, "description", acct_desc))
96 sam21->acct_desc = acct_desc;
98 if (ldapdb_get_pvalue (hds, "userWorkstations", workstations))
99 sam21->workstations = workstations;
101 /* uidNumber from smbpw */
103 if (ldapdb_get_pvalue (hds, "gidNumber", temp))
104 sam21->unix_gid = atoi (temp);
106 /* objectSid from smbpw */
108 if (ldapdb_get_pvalue (hds, "primaryGroupId", temp))
109 sam21->group_rid = strtol (temp, NULL, 10);
111 /* dBCSPwd/unicodePwd from smbpw */
113 (void) ldapdb_get_time (hds, "lastLogon", &sam21->logon_time);
114 (void) ldapdb_get_time (hds, "lastLogoff", &sam21->logoff_time);
115 (void) ldapdb_get_time (hds, "accountExpires", &sam21->pass_must_change_time);
116 #if 0
117 /* not sure about this */
118 (void) ldapdb_get_time (hds, "pwdCanChange", &sam21->pass_can_change_time);
119 (void) ldapdb_get_time (hds, "kickoffTime", &sam21->kickoff_time);
120 #endif
122 if (ldapdb_get_value_len(hds, "logonHours", &bv))
124 if (bv->bv_len <= MAX_HOURS_LEN)
126 memcpy(sam21->hours, bv->bv_val, bv->bv_len);
127 sam21->hours_len = bv->bv_len;
129 ber_bvfree(bv);
132 sam21->unknown_3 = 0xffffff; /* don't know */
133 sam21->logon_divs = 168; /* hours per week */
134 sam21->unknown_5 = 0x00020000; /* don't know */
135 sam21->unknown_6 = 0x000004ec; /* don't know */
136 sam21->unknown_str = NULL;
137 sam21->munged_dial = NULL;
139 /* XXXX hack to get standard_sub_basic() to use sam logon username */
140 /* possibly a better way would be to do a become_user() call */
142 sam_logon_in_ssb = True;
144 pstrcpy (samlogon_user, sam21->unix_name);
146 standard_sub_basic (logon_script);
147 standard_sub_basic (profile_path);
148 standard_sub_basic (home_drive);
149 standard_sub_basic (home_dir);
150 standard_sub_basic (workstations);
152 sam_logon_in_ssb = False;
154 return sam21;
158 /*******************************************************************
159 Contruct a sam_disp_info structure.
160 ******************************************************************/
162 static struct sam_disp_info *
163 nt5ldapsam_getdispinfo (LDAPDB * hds)
165 static struct sam_disp_info dispinfo;
166 static pstring nt_name;
167 static pstring full_name;
169 if (!ldapdb_peek (hds))
171 return NULL;
174 if (!ldapdb_get_pvalue (hds, "sAMAccountName", nt_name))
176 DEBUG (0, ("SAM user missing sAMAccountName\n"));
177 return NULL;
179 dispinfo.nt_name = nt_name;
181 DEBUG (2, ("Retrieving account [%s]\n", nt_name));
183 if (!ldapdb_get_rid (hds, "objectSid", &dispinfo.user_rid))
185 DEBUG (0, ("SAM user missing objectSid\n"));
186 return NULL;
189 if (ldapdb_get_pvalue (hds, "displayName", full_name) ||
190 ldapdb_get_pvalue (hds, "cn", full_name))
192 dispinfo.full_name = full_name;
194 else
196 dispinfo.full_name = nt_name;
199 return &dispinfo;
203 /************************************************************************
204 Queues the necessary modifications to save a sam_passwd structure
205 ************************************************************************/
207 BOOL
208 nt5ldapsam_sammods (struct sam_passwd * newpwd, LDAPMod *** mods, int operation)
210 struct smb_passwd *smbpw;
211 pstring temp;
212 struct berval *bv;
214 smbpw = pwdb_sam_to_smb (newpwd);
215 if (!nt5ldapsmb_smbmods (smbpw, mods, operation))
217 return False;
220 slprintf (temp, sizeof (temp) - 1, "%d", newpwd->unix_gid);
221 if (!ldapdb_queue_mod (mods, operation, "gidNumber", temp) ||
222 !ldapdb_queue_mod (mods, operation, "cn", newpwd->full_name) ||
223 !ldapdb_queue_mod (mods, operation, "name", newpwd->full_name) ||
224 !ldapdb_queue_mod (mods, operation, "displayName", newpwd->full_name) ||
225 !ldapdb_queue_mod (mods, operation, "description", newpwd->acct_desc) ||
226 !ldapdb_queue_mod (mods, operation, "homeDirectory", newpwd->home_dir) ||
227 !ldapdb_queue_mod (mods, operation, "homeDrive", newpwd->dir_drive) ||
228 !ldapdb_queue_mod (mods, operation, "scriptPath", newpwd->logon_script) ||
229 !ldapdb_queue_mod (mods, operation, "profilePath", newpwd->profile_path) ||
230 !ldapdb_queue_mod (mods, operation, "userWorkstations", newpwd->workstations) ||
231 !ldapdb_queue_time (mods, operation, "lastLogon", &newpwd->logon_time) ||
232 !ldapdb_queue_time (mods, operation, "lastLogoff", &newpwd->logoff_time) ||
233 !ldapdb_queue_time (mods, operation, "accountExpires", &newpwd->pass_must_change_time))
235 return False;
238 if (newpwd->hours_len)
240 bv = (struct berval *)malloc(sizeof(*bv));
241 if (bv == NULL)
243 return False;
245 bv->bv_len = newpwd->hours_len;
246 bv->bv_val = malloc(newpwd->hours_len);
247 if (bv->bv_val == NULL)
249 free(bv);
250 return False;
253 memcpy(bv->bv_val, newpwd->hours, newpwd->hours_len);
254 if (!ldapdb_queue_mod_len(mods, operation, "logonHours", bv))
256 ber_bvfree(bv);
257 return False;
261 #if 0
262 /* not sure about this */
263 if (!ldapdb_queue_time (mods, operation, "pwdCanChange", &newpwd->pass_can_change_time) ||
264 !ldapdb_queue_time (mods, operation, "kickoffTime", &newpwd->kickoff_time))
266 return False;
268 #endif
270 return True;
274 /***************************************************************
275 Begin/end account enumeration.
276 ****************************************************************/
278 static void *
279 nt5ldapsam_enumfirst (BOOL update)
281 LDAPDB_DECLARE_HANDLE (hds);
283 if (!ldapdb_open (&hds))
285 return NULL;
288 if (!ldapdb_search (hds, NULL, "(objectClass=User)", NULL, LDAP_NO_LIMIT))
290 ldapdb_close (&hds);
291 return NULL;
294 return hds;
297 static void
298 nt5ldapsam_enumclose (void *vp)
300 LDAPDB *hds = (LDAPDB *) vp;
302 ldapdb_close (&hds);
304 return;
308 /*************************************************************************
309 Save/restore the current position in a query
310 *************************************************************************/
312 static SMB_BIG_UINT
313 nt5ldapsam_getdbpos (void *vp)
315 return 0;
318 static BOOL
319 nt5ldapsam_setdbpos (void *vp, SMB_BIG_UINT tok)
321 return False;
325 /*************************************************************************
326 Return sam_passwd information.
327 *************************************************************************/
329 static struct sam_passwd *
330 nt5ldapsam_getsambynam (const char *name)
332 struct sam_passwd *ret;
333 LDAPDB_DECLARE_HANDLE (hds);
335 if (!ldapdb_open (&hds))
337 return NULL;
340 if (!ldapdb_lookup_by_ntname (hds, name))
342 ldapdb_close (&hds);
343 return NULL;
346 ret = nt5ldapsam_getent (hds);
348 ldapdb_close (&hds);
350 return ret;
353 static struct sam_passwd *
354 nt5ldapsam_getsambyuid (uid_t userid)
356 struct sam_passwd *ret;
357 LDAPDB_DECLARE_HANDLE (hds);
359 if (!ldapdb_open (&hds))
361 return NULL;
364 if (!ldapdb_lookup_by_posix_uid (hds, userid))
366 ldapdb_close (&hds);
367 return NULL;
370 ret = nt5ldapsam_getent (hds);
372 ldapdb_close (&hds);
374 return ret;
377 static struct sam_passwd *
378 nt5ldapsam_getsambyrid (uint32 user_rid)
380 struct sam_passwd *ret;
381 LDAPDB_DECLARE_HANDLE (hds);
383 if (!ldapdb_open (&hds))
385 return NULL;
388 if (!ldapdb_lookup_by_rid (hds, user_rid))
390 ldapdb_close (&hds);
391 return NULL;
394 ret = nt5ldapsam_getent (hds);
396 ldapdb_close (&hds);
398 return ret;
401 static struct sam_passwd *
402 nt5ldapsam_getcurrentsam (void *vp)
404 struct sam_passwd *ret = NULL;
408 if ((ret = nt5ldapsam_getent ((LDAPDB *)vp)) != NULL)
409 break;
411 while (ldapdb_seq((LDAPDB *)vp) == True);
413 return ret;
417 /************************************************************************
418 Modify user information given a sam_passwd struct.
419 *************************************************************************/
421 static BOOL
422 nt5ldapsam_addsam (struct sam_passwd *newpwd)
424 LDAPMod **mods = NULL;
425 char *container, *cname;
426 pstring hostname;
427 LDAPDB_DECLARE_HANDLE (hds);
428 BOOL ret;
430 if (!ldapdb_open (&hds))
432 return False;
435 if (!newpwd || !ldapdb_allocate_rid (hds, &newpwd->user_rid))
437 ldapdb_close (&hds);
438 return False;
441 if (newpwd->unix_name[strlen (newpwd->unix_name) - 2] == '$')
443 container = lp_ldap_computers_subcontext ();
444 pstrcpy (hostname, newpwd->nt_name);
445 hostname[strlen (hostname) - 1] = '\0';
446 cname = hostname;
448 else
450 container = lp_ldap_users_subcontext ();
451 cname = newpwd->full_name;
454 if (!nt5ldapsam_sammods (newpwd, &mods, LDAP_MOD_ADD))
456 ret = False;
458 else
460 ret = ldapdb_update (hds, container, "cn", cname, mods, True);
463 ldapdb_close (&hds);
465 return ret;
468 static BOOL
469 nt5ldapsam_modsam (struct sam_passwd *pwd, BOOL override)
471 LDAPMod **mods = NULL;
472 LDAPDB_DECLARE_HANDLE (hds);
473 BOOL ret;
475 if (!pwd)
477 return False;
480 if (!ldapdb_open (&hds))
482 return False;
485 if (!nt5ldapsam_sammods (pwd, &mods, LDAP_MOD_REPLACE))
487 ret = False;
489 else
491 ret = ldapdb_update (hds, NULL, "cn", pwd->full_name, mods, False);
494 ldapdb_close (&hds);
496 return ret;
500 /*************************************************************************
501 Return sam_disp_info information.
502 *************************************************************************/
504 static struct sam_disp_info *
505 nt5ldapsam_getdispbynam (const char *name)
507 struct sam_disp_info *ret;
508 LDAPDB_DECLARE_HANDLE (hds);
510 if (!ldapdb_open (&hds))
512 return NULL;
515 if (!ldapdb_lookup_by_ntname (hds, name))
517 ldapdb_close (&hds);
518 return NULL;
521 ret = nt5ldapsam_getdispinfo (hds);
523 ldapdb_close (&hds);
525 return ret;
528 static struct sam_disp_info *
529 nt5ldapsam_getdispbyrid (uint32 user_rid)
531 struct sam_disp_info *ret;
532 LDAPDB_DECLARE_HANDLE (hds);
534 if (!ldapdb_open (&hds))
536 return NULL;
539 if (!ldapdb_lookup_by_rid (hds, user_rid))
541 ldapdb_close (&hds);
542 return NULL;
545 ret = nt5ldapsam_getdispinfo (hds);
547 ldapdb_close (&hds);
549 return ret;
552 static struct sam_disp_info *
553 nt5ldapsam_getcurrentdisp (void *vp)
555 struct sam_disp_info *ret = NULL;
559 if ((ret = nt5ldapsam_getdispinfo ((LDAPDB *)vp)) != NULL)
560 break;
562 while (ldapdb_seq((LDAPDB *)vp) == True);
564 return ret;
567 static struct sam_passdb_ops nt5ldapsam_ops =
569 nt5ldapsam_enumfirst,
570 nt5ldapsam_enumclose,
571 nt5ldapsam_getdbpos,
572 nt5ldapsam_setdbpos,
574 nt5ldapsam_getsambynam,
575 nt5ldapsam_getsambyuid,
576 nt5ldapsam_getsambyrid,
577 nt5ldapsam_getcurrentsam,
578 nt5ldapsam_addsam,
579 nt5ldapsam_modsam,
581 nt5ldapsam_getdispbynam,
582 nt5ldapsam_getdispbyrid,
583 nt5ldapsam_getcurrentdisp
586 struct sam_passdb_ops *
587 nt5ldap_initialise_sam_password_db (void)
589 return &nt5ldapsam_ops;
592 #else
593 void sampassnt5ldap_dummy_function (void);
594 void
595 sampassnt5ldap_dummy_function (void)
597 } /* stop some compilers complaining */
598 #endif