3 Unix SMB/Netbios implementation.
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.
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 ******************************************************************/
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
;
58 extern BOOL sam_logon_in_ssb
;
59 extern pstring samlogon_user
;
61 if (!ldapdb_peek (hds
))
66 smbpw
= nt5ldapsmb_getent (hds
);
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
);
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
);
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
;
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
;
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
))
174 if (!ldapdb_get_pvalue (hds
, "sAMAccountName", nt_name
))
176 DEBUG (0, ("SAM user missing sAMAccountName\n"));
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"));
189 if (ldapdb_get_pvalue (hds
, "displayName", full_name
) ||
190 ldapdb_get_pvalue (hds
, "cn", full_name
))
192 dispinfo
.full_name
= full_name
;
196 dispinfo
.full_name
= nt_name
;
203 /************************************************************************
204 Queues the necessary modifications to save a sam_passwd structure
205 ************************************************************************/
208 nt5ldapsam_sammods (struct sam_passwd
* newpwd
, LDAPMod
*** mods
, int operation
)
210 struct smb_passwd
*smbpw
;
214 smbpw
= pwdb_sam_to_smb (newpwd
);
215 if (!nt5ldapsmb_smbmods (smbpw
, mods
, operation
))
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
))
238 if (newpwd
->hours_len
)
240 bv
= (struct berval
*)malloc(sizeof(*bv
));
245 bv
->bv_len
= newpwd
->hours_len
;
246 bv
->bv_val
= malloc(newpwd
->hours_len
);
247 if (bv
->bv_val
== NULL
)
253 memcpy(bv
->bv_val
, newpwd
->hours
, newpwd
->hours_len
);
254 if (!ldapdb_queue_mod_len(mods
, operation
, "logonHours", bv
))
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
))
274 /***************************************************************
275 Begin/end account enumeration.
276 ****************************************************************/
279 nt5ldapsam_enumfirst (BOOL update
)
281 LDAPDB_DECLARE_HANDLE (hds
);
283 if (!ldapdb_open (&hds
))
288 if (!ldapdb_search (hds
, NULL
, "(objectClass=User)", NULL
, LDAP_NO_LIMIT
))
298 nt5ldapsam_enumclose (void *vp
)
300 LDAPDB
*hds
= (LDAPDB
*) vp
;
308 /*************************************************************************
309 Save/restore the current position in a query
310 *************************************************************************/
313 nt5ldapsam_getdbpos (void *vp
)
319 nt5ldapsam_setdbpos (void *vp
, SMB_BIG_UINT tok
)
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
))
340 if (!ldapdb_lookup_by_ntname (hds
, name
))
346 ret
= nt5ldapsam_getent (hds
);
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
))
364 if (!ldapdb_lookup_by_posix_uid (hds
, userid
))
370 ret
= nt5ldapsam_getent (hds
);
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
))
388 if (!ldapdb_lookup_by_rid (hds
, user_rid
))
394 ret
= nt5ldapsam_getent (hds
);
401 static struct sam_passwd
*
402 nt5ldapsam_getcurrentsam (void *vp
)
404 struct sam_passwd
*ret
= NULL
;
408 if ((ret
= nt5ldapsam_getent ((LDAPDB
*)vp
)) != NULL
)
411 while (ldapdb_seq((LDAPDB
*)vp
) == True
);
417 /************************************************************************
418 Modify user information given a sam_passwd struct.
419 *************************************************************************/
422 nt5ldapsam_addsam (struct sam_passwd
*newpwd
)
424 LDAPMod
**mods
= NULL
;
425 char *container
, *cname
;
427 LDAPDB_DECLARE_HANDLE (hds
);
430 if (!ldapdb_open (&hds
))
435 if (!newpwd
|| !ldapdb_allocate_rid (hds
, &newpwd
->user_rid
))
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';
450 container
= lp_ldap_users_subcontext ();
451 cname
= newpwd
->full_name
;
454 if (!nt5ldapsam_sammods (newpwd
, &mods
, LDAP_MOD_ADD
))
460 ret
= ldapdb_update (hds
, container
, "cn", cname
, mods
, True
);
469 nt5ldapsam_modsam (struct sam_passwd
*pwd
, BOOL override
)
471 LDAPMod
**mods
= NULL
;
472 LDAPDB_DECLARE_HANDLE (hds
);
480 if (!ldapdb_open (&hds
))
485 if (!nt5ldapsam_sammods (pwd
, &mods
, LDAP_MOD_REPLACE
))
491 ret
= ldapdb_update (hds
, NULL
, "cn", pwd
->full_name
, mods
, False
);
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
))
515 if (!ldapdb_lookup_by_ntname (hds
, name
))
521 ret
= nt5ldapsam_getdispinfo (hds
);
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
))
539 if (!ldapdb_lookup_by_rid (hds
, user_rid
))
545 ret
= nt5ldapsam_getdispinfo (hds
);
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
)
562 while (ldapdb_seq((LDAPDB
*)vp
) == True
);
567 static struct sam_passdb_ops nt5ldapsam_ops
=
569 nt5ldapsam_enumfirst
,
570 nt5ldapsam_enumclose
,
574 nt5ldapsam_getsambynam
,
575 nt5ldapsam_getsambyuid
,
576 nt5ldapsam_getsambyrid
,
577 nt5ldapsam_getcurrentsam
,
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
;
593 void sampassnt5ldap_dummy_function (void);
595 sampassnt5ldap_dummy_function (void)
597 } /* stop some compilers complaining */