4 * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
5 * Copyright (C) Benny Holmgren 1998 <bigfoot@astrakan.hgs.se>
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998.
7 * Copyright (C) Toomas Soome <tsoome@ut.ee> 2001
8 * Copyright (C) Jelmer Vernooij 2002
10 * This program is free software; you can redistribute it and/or modify it under
11 * the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20 * You should have received a copy of the GNU General Public License along with
21 * this program; if not, write to the Free Software Foundation, Inc., 675
22 * Mass Ave, Cambridge, MA 02139, USA.
27 #ifdef WITH_NISPLUS_SAM
29 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
32 * The following lines are needed due to buggy include files
33 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
34 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
35 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
36 * an enum in /usr/include/rpcsvc/nis.h.
44 #if defined(GROUP_OBJ)
50 #include <rpcsvc/nis.h>
52 /***************************************************************
54 the fields for the NIS+ table, generated from mknissmbpwtbl.sh, are:
83 ****************************************************************/
87 #define NPF_USER_RID 2
88 #define NPF_SMB_GRPID 3
89 #define NPF_GROUP_RID 4
94 #define NPF_LOGOFF_T 9
96 #define NPF_PWDLSET_T 11
97 #define NPF_PWDCCHG_T 12
98 #define NPF_PWDMCHG_T 13
99 #define NPF_FULL_NAME 14
100 #define NPF_HOME_DIR 15
101 #define NPF_DIR_DRIVE 16
102 #define NPF_LOGON_SCRIPT 17
103 #define NPF_PROFILE_PATH 18
104 #define NPF_ACCT_DESC 19
105 #define NPF_WORKSTATIONS 20
108 struct nisplus_private_info {
114 static char *make_nisname_from_user_rid (uint32 rid, char *pfile);
115 static char *make_nisname_from_name (const char *user_name, char *pfile);
116 static void get_single_attribute (const nis_object * new_obj, int col,
117 char *val, int len);;
118 static BOOL make_sam_from_nisp_object (SAM_ACCOUNT * pw_buf,
119 const nis_object * obj);
120 static BOOL make_sam_from_nisresult (SAM_ACCOUNT * pw_buf,
121 const nis_result * result);;
122 static void set_single_attribute (nis_object * new_obj, int col,
123 const char *val, int len, int flags);
124 static BOOL init_nisp_from_sam (nis_object * obj, const SAM_ACCOUNT * sampass,
126 static nis_result *nisp_get_nis_list (const char *nisname,
129 /***************************************************************
130 Start enumeration of the passwd list.
131 ****************************************************************/
133 static NTSTATUS nisplussam_setsampwent (struct pdb_methods *methods, BOOL update)
135 struct nisplus_private_info *private =
136 (struct nisplus_private_info *) methods->private_data;
141 if ((sp = strrchr (private->location, '/')))
142 safe_strcpy (pfiletmp, sp + 1, sizeof (pfiletmp) - 1);
144 safe_strcpy (pfiletmp, p, sizeof (pfiletmp) - 1);
145 safe_strcat (pfiletmp, ".org_dir",
146 sizeof (pfiletmp) - strlen (pfiletmp) - 1);
148 pdb_endsampwent (); /* just in case */
149 global_nisp_ent->result = nisp_get_nis_list (pfiletmp, 0);
150 global_nisp_ent->enum_entry = 0;
151 if (global_nisp_ent->result != NULL)
152 return NT_STATUS_UNSUCCESSFUL;
157 /***************************************************************
158 End enumeration of the passwd list.
159 ****************************************************************/
161 static void nisplussam_endsampwent (struct pdb_methods *methods)
163 struct nisplus_private_info *global_nisp_ent =
164 (struct nisplus_private_info *) methods->private_data;
165 if (global_nisp_ent->result)
166 nis_freeresult (global_nisp_ent->result);
167 global_nisp_ent->result = NULL;
168 global_nisp_ent->enum_entry = 0;
171 /*****************************************************************
172 Get one SAM_ACCOUNT from the list (next in line)
173 *****************************************************************/
175 static NTSTATUS nisplussam_getsampwent (struct pdb_methods *methods,
178 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
179 struct nisplus_private_info *global_nisp_ent =
180 (struct nisplus_private_info *) methods->private_data;
181 int enum_entry = (int) (global_nisp_ent->enum_entry);
182 nis_result *result = global_nisp_ent->result;
185 DEBUG (0, ("SAM_ACCOUNT is NULL.\n"));
189 if (result == NULL || enum_entry < 0 || enum_entry >= (NIS_RES_NUMOBJ (result) - 1)) {
193 if (!make_sam_from_nisp_object(user, &NIS_RES_OBJECT (result)[enum_entry])) {
194 DEBUG (0, ("Bad SAM_ACCOUNT entry returned from NIS+!\n"));
197 (int) (global_nisp_ent->enum_entry)++;
202 /******************************************************************
203 Lookup a name in the SAM database
204 ******************************************************************/
206 static NTSTATUS nisplussam_getsampwnam (struct pdb_methods *methods,
207 SAM_ACCOUNT * user, const char *sname)
209 /* Static buffers we will return. */
210 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
211 nis_result *result = NULL;
214 struct nisplus_private_info *private =
215 (struct nisplus_private_info *) methods->private_data;
217 if (!private->location || !(*private->location)) {
218 DEBUG (0, ("No SMB password file set\n"));
221 if (strrchr (private->location, '/'))
222 private->location = strrchr (private->location, '/') + 1;
224 slprintf (nisname, sizeof (nisname) - 1, "[name=%s],%s.org_dir",
225 sname, private->location);
226 DEBUG (10, ("search by nisname: %s\n", nisname));
228 /* Search the table. */
230 if (!(result = nisp_get_nis_list (nisname, 0))) {
234 ret = make_sam_from_nisresult (user, result);
235 nis_freeresult (result);
237 if (ret) nt_status = NT_STATUS_OK;
242 /***************************************************************************
244 **************************************************************************/
246 static NTSTATUS nisplussam_getsampwrid (struct pdb_methods *methods,
247 SAM_ACCOUNT * user, uint32 rid)
249 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
255 struct nisplus_private_info *private =
256 (struct nisplus_private_info *) methods->private_data;
258 if (!private->location || !(*private->location)) {
259 DEBUG (0, ("no SMB password file set\n"));
263 if ((sp = strrchr (private->location, '/')))
264 safe_strcpy (pfiletmp, sp + 1, sizeof (pfiletmp) - 1);
266 safe_strcpy (pfiletmp, private->location, sizeof (pfiletmp) - 1);
267 safe_strcat (pfiletmp, ".org_dir",
268 sizeof (pfiletmp) - strlen (pfiletmp) - 1);
270 nisname = make_nisname_from_user_rid (rid, pfiletmp);
272 DEBUG (10, ("search by rid: %s\n", nisname));
274 /* Search the table. */
276 if (!(result = nisp_get_nis_list (nisname, 0))) {
280 ret = make_sam_from_nisresult (user, result);
281 nis_freeresult (result);
283 if (ret) nt_status = NT_STATUS_OK;
288 static NTSTATUS nisplussam_getsampwsid (struct pdb_methods *methods,
289 SAM_ACCOUNT * user, const DOM_SID * sid)
293 if (!sid_peek_check_rid (get_global_sam_sid (), sid, &rid))
294 return NT_STATUS_UNSUCCESSFUL;
295 return nisplussam_getsampwrid (methods, user, rid);
300 /***************************************************************************
302 ****************************************************************************/
304 static NTSTATUS nisplussam_delete_sam_account (struct pdb_methods *methods,
307 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
310 nis_result *result, *delresult;
312 struct nisplus_private_info *private =
313 (struct nisplus_private_info *) methods->private_data;
316 DEBUG (0, ("no SAM_ACCOUNT specified!\n"));
320 sname = pdb_get_username (user);
322 if (!private->location || !(*private->location)) {
323 DEBUG (0, ("no SMB password file set\n"));
327 if (strrchr (private->location, '/'))
328 private->location = strrchr (private->location, '/') + 1;
330 slprintf (nisname, sizeof (nisname) - 1, "[name=%s],%s.org_dir",
331 sname, private->location);
333 /* Search the table. */
335 if (!(result = nisp_get_nis_list (nisname,
336 MASTER_ONLY | FOLLOW_LINKS |
337 FOLLOW_PATH | EXPAND_NAME |
342 if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ (result) <= 0) {
343 /* User not found. */
344 DEBUG (0, ("user not found in NIS+\n"));
345 nis_freeresult (result);
349 obj = NIS_RES_OBJECT (result);
350 slprintf (nisname, sizeof (nisname) - 1, "[name=%s],%s.%s", sname,
351 obj->zo_name, obj->zo_domain);
353 DEBUG (10, ("removing name: %s\n", nisname));
354 delresult = nis_remove_entry (nisname, obj,
355 MASTER_ONLY | REM_MULTIPLE | ALL_RESULTS
356 | FOLLOW_PATH | EXPAND_NAME |
359 nis_freeresult (result);
361 if (delresult->status != NIS_SUCCESS) {
362 DEBUG (0, ("NIS+ table update failed: %s %s\n",
363 nisname, nis_sperrno (delresult->status)));
364 nis_freeresult (delresult);
367 nis_freeresult (delresult);
372 /***************************************************************************
373 Modifies an existing SAM_ACCOUNT
374 ****************************************************************************/
376 static NTSTATUS nisplussam_update_sam_account (struct pdb_methods *methods,
377 SAM_ACCOUNT * newpwd)
379 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
380 nis_result *result, *addresult;
385 struct nisplus_private_info *private =
386 (struct nisplus_private_info *) methods->private_data;
389 if (!private->location || !(*private->location)) {
390 DEBUG (0, ("no SMB password file set\n"));
393 if (strrchr (private->location, '/'))
394 private->location = strrchr (private->location, '/') + 1;
396 slprintf (nisname, sizeof (nisname) - 1, "[name=%s],%s.org_dir",
397 pdb_get_username (newpwd), private->location);
399 DEBUG (10, ("search by name: %s\n", nisname));
401 /* Search the table. */
405 nisp_get_nis_list (nisname,
406 MASTER_ONLY | FOLLOW_LINKS | FOLLOW_PATH |
407 EXPAND_NAME | HARD_LOOKUP))) {
411 if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ (result) <= 0) {
412 /* User not found. */
413 DEBUG (0, ("user not found in NIS+\n"));
414 nis_freeresult (result);
418 obj = NIS_RES_OBJECT (result);
419 DEBUG (6, ("entry found in %s\n", obj->zo_domain));
421 /* we must create new stub object with EN_MODIFIED flag.
422 this is because obj from result is going to be freed and
423 we do not want to break it or cause memory leaks or corruption.
426 memmove ((char *) &new_obj, obj, sizeof (new_obj));
427 ta_maxcol = obj->TA_data.ta_maxcol;
429 if (!(ecol = (entry_col *) malloc (ta_maxcol * sizeof (entry_col)))) {
430 DEBUG (0, ("memory allocation failure\n"));
431 nis_freeresult (result);
435 memmove ((char *) ecol, obj->EN_data.en_cols.en_cols_val,
436 ta_maxcol * sizeof (entry_col));
437 new_obj.EN_data.en_cols.en_cols_val = ecol;
438 new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
440 if (init_nisp_from_sam (&new_obj, newpwd, obj) == True) {
441 slprintf (nisname, sizeof (nisname) - 1, "[name=%s],%s.%s",
442 pdb_get_username (newpwd), private->location, obj->zo_domain);
444 DEBUG (10, ("NIS+ table update: %s\n", nisname));
446 nis_modify_entry (nisname, &new_obj,
447 MOD_SAMEOBJ | FOLLOW_PATH |
448 EXPAND_NAME | HARD_LOOKUP);
450 if (addresult->status != NIS_SUCCESS) {
451 DEBUG (0, ("NIS+ table update failed: %s %s\n",
452 nisname, nis_sperrno (addresult->status)));
453 nis_freeresult (addresult);
454 nis_freeresult (result);
459 DEBUG (6, ("password changed\n"));
460 nis_freeresult (addresult);
462 DEBUG (6, ("nothing to change!\n"));
466 nis_freeresult (result);
471 /***************************************************************************
472 Adds an existing SAM_ACCOUNT
473 ****************************************************************************/
475 static NTSTATUS nisplussam_add_sam_account (struct pdb_methods *methods,
476 SAM_ACCOUNT * newpwd)
478 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
483 nis_result *result = NULL, *tblresult = NULL;
489 * 1. find user domain.
490 * a. try nis search in passwd.org_dir - if found use domain from result.
491 * b. try getpwnam. this may be needed if user is defined
492 * in /etc/passwd file (or elsewere) and not in passwd.org_dir.
493 * if found, use host default domain.
494 * c. exit with False - no such user.
497 * a. find smbpasswd table
498 * search pfile in user domain if not found, try host default
500 * b. smbpasswd domain is found, fill data and add entry.
502 * pfile should contain ONLY table name, org_dir will be concated.
503 * so, at first we will clear path prefix from pfile, and
504 * then we will use pfiletmp as playground to put together full
506 * such approach will make it possible to specify samba private dir
507 * AND still use NIS+ table. as all domain related data is normally
508 * stored in org_dir.DOMAIN, this should be ok do do.
511 pfile = private->location;
512 if (strrchr (pfile, '/'))
513 pfile = strrchr (pfile, '/') + 1;
516 * Check if user is already there.
518 safe_strcpy (pfiletmp, pfile, sizeof (pfiletmp) - 1);
519 safe_strcat (pfiletmp, ".org_dir",
520 sizeof (pfiletmp) - strlen (pfiletmp) - 1);
522 if (pdb_get_username (newpwd) != NULL) {
523 nisname = make_nisname_from_name (pdb_get_username (newpwd),
531 nisp_get_nis_list (nisname,
532 MASTER_ONLY | FOLLOW_LINKS | FOLLOW_PATH |
533 EXPAND_NAME | HARD_LOOKUP))) {
536 if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND) {
537 DEBUG (3, ("nis_list failure: %s: %s\n",
538 nisname, nis_sperrno (result->status)));
539 nis_freeresult (result);
543 if (result->status == NIS_SUCCESS && NIS_RES_NUMOBJ (result) > 0) {
544 DEBUG (3, ("User already exists in NIS+ password db: %s\n",
546 nis_freeresult (result);
550 nis_freeresult (result); /* no such user, free results */
553 * check for user in unix password database. we need this to get
554 * domain, where smbpasswd entry should be stored.
557 nisname = make_nisname_from_name (pdb_get_username (newpwd),
560 result = nisp_get_nis_list (nisname,
561 MASTER_ONLY | FOLLOW_LINKS | FOLLOW_PATH |
562 EXPAND_NAME | HARD_LOOKUP);
564 if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ (result) <= 0) {
565 struct passwd *passwd;
567 DEBUG (3, ("nis_list failure: %s: %s\n",
568 nisname, nis_sperrno (result->status)));
569 nis_freeresult (result);
571 if (!(passwd = getpwnam_alloc (pdb_get_username (newpwd)))) {
572 /* no such user in system! */
575 passwd_free (&passwd);
578 * user is defined, but not in passwd.org_dir.
582 safe_strcpy (pfiletmp, pfile, sizeof (pfiletmp) - 1);
583 safe_strcat (pfiletmp, ".",
584 sizeof (pfiletmp) - strlen (pfiletmp) - 1);
585 safe_strcat (pfiletmp, NIS_RES_OBJECT (result)->zo_domain,
586 sizeof (pfiletmp) - strlen (pfiletmp) - 1);
587 nis_freeresult (result); /* not needed any more */
589 tblresult = nisp_get_nis_list (pfiletmp,
590 MASTER_ONLY | FOLLOW_LINKS |
591 FOLLOW_PATH | EXPAND_NAME |
595 if (local_user || tblresult->status != NIS_SUCCESS) {
598 * smbpasswd table not found in user domain, fallback to
601 if (!local_user) /* free previous failed search result */
602 nis_freeresult (tblresult);
604 safe_strcpy (pfiletmp, pfile, sizeof (pfiletmp) - 1);
605 safe_strcat (pfiletmp, ".org_dir",
606 sizeof (pfiletmp) - strlen (pfiletmp) - 1);
607 tblresult = nis_lookup (pfiletmp, MASTER_ONLY | FOLLOW_LINKS |
608 FOLLOW_PATH | EXPAND_NAME |
610 if (tblresult->status != NIS_SUCCESS) {
611 /* still nothing. bail out */
612 nis_freeresult (tblresult);
613 DEBUG (3, ("nis_lookup failure: %s\n",
614 nis_sperrno (tblresult->status)));
617 /* we need full name for nis_add_entry() */
618 safe_strcpy (pfiletmp, pfile, sizeof (pfiletmp) - 1);
619 safe_strcat (pfiletmp, ".",
620 sizeof (pfiletmp) - strlen (pfiletmp) - 1);
621 safe_strcat (pfiletmp, NIS_RES_OBJECT (tblresult)->zo_domain,
622 sizeof (pfiletmp) - strlen (pfiletmp) - 1);
625 memset ((char *) &new_obj, 0, sizeof (new_obj));
626 /* fill entry headers */
627 /* we do not free these. */
628 new_obj.zo_name = NIS_RES_OBJECT (tblresult)->zo_name;
629 new_obj.zo_owner = NIS_RES_OBJECT (tblresult)->zo_owner;
630 new_obj.zo_group = NIS_RES_OBJECT (tblresult)->zo_group;
631 new_obj.zo_domain = NIS_RES_OBJECT (tblresult)->zo_domain;
633 new_obj.zo_access = NIS_RES_OBJECT (tblresult)->zo_access;
634 new_obj.zo_ttl = NIS_RES_OBJECT (tblresult)->zo_ttl;
636 new_obj.zo_data.zo_type = ENTRY_OBJ;
637 new_obj.EN_data.en_type = NIS_RES_OBJECT (tblresult)->TA_data.ta_type;
639 ta_maxcol = NIS_RES_OBJECT (tblresult)->TA_data.ta_maxcol;
641 if (!(ecol = (entry_col *) malloc (ta_maxcol * sizeof (entry_col)))) {
642 DEBUG (0, ("memory allocation failure\n"));
643 nis_freeresult (tblresult);
647 memset ((char *) ecol, 0, ta_maxcol * sizeof (entry_col));
648 new_obj.EN_data.en_cols.en_cols_val = ecol;
649 new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
651 init_nisp_from_sam (&new_obj, newpwd, NULL);
653 DEBUG (10, ("add NIS+ entry: %s\n", nisname));
654 result = nis_add_entry (pfiletmp, &new_obj, 0);
656 free (ecol); /* free allocated entry space */
658 if (result->status != NIS_SUCCESS) {
659 DEBUG (3, ("NIS+ table update failed: %s,%s\n",
660 nisname, nis_sperrno (result->status)));
661 nis_freeresult (tblresult);
662 nis_freeresult (result);
666 nis_freeresult (tblresult);
667 nis_freeresult (result);
672 /***************************************************************
673 make_nisname_from_user_rid
674 ****************************************************************/
675 static char *make_nisname_from_user_rid (uint32 rid, char *pfile)
677 static pstring nisname;
679 safe_strcpy (nisname, "[user_rid=", sizeof (nisname) - 1);
680 slprintf (nisname, sizeof (nisname) - 1, "%s%d", nisname, rid);
681 safe_strcat (nisname, "],", sizeof (nisname) - strlen (nisname) - 1);
682 safe_strcat (nisname, pfile, sizeof (nisname) - strlen (nisname) - 1);
687 /***************************************************************
688 make_nisname_from_name
689 ****************************************************************/
690 static char *make_nisname_from_name (const char *user_name, char *pfile)
692 static pstring nisname;
694 safe_strcpy (nisname, "[name=", sizeof (nisname) - 1);
695 safe_strcat (nisname, user_name,
696 sizeof (nisname) - strlen (nisname) - 1);
697 safe_strcat (nisname, "],", sizeof (nisname) - strlen (nisname) - 1);
698 safe_strcat (nisname, pfile, sizeof (nisname) - strlen (nisname) - 1);
703 /*************************************************************************
704 gets a NIS+ attribute
705 *************************************************************************/
706 static void get_single_attribute (const nis_object * new_obj, int col,
711 if (new_obj == NULL || val == NULL)
714 entry_len = ENTRY_LEN (new_obj, col);
715 if (len > entry_len) {
719 safe_strcpy (val, ENTRY_VAL (new_obj, col), len - 1);
722 /************************************************************************
723 makes a struct sam_passwd from a NIS+ object.
724 ************************************************************************/
725 static BOOL make_sam_from_nisp_object (SAM_ACCOUNT * pw_buf,
726 const nis_object * obj)
729 pstring full_name; /* this must be translated to dos code page */
730 pstring acct_desc; /* this must be translated to dos code page */
731 pstring home_dir; /* set default value from smb.conf for user */
732 pstring home_drive; /* set default value from smb.conf for user */
733 pstring logon_script; /* set default value from smb.conf for user */
734 pstring profile_path; /* set default value from smb.conf for user */
737 unsigned char smbpwd[16];
738 unsigned char smbntpwd[16];
742 * time values. note: this code assumes 32bit time_t!
745 /* Don't change these timestamp settings without a good reason. They are
746 important for NT member server compatibility. */
748 pdb_set_logon_time (pw_buf, (time_t) 0, PDB_DEFAULT);
749 ptr = (uchar *) ENTRY_VAL (obj, NPF_LOGON_T);
750 if (ptr && *ptr && (StrnCaseCmp (ptr, "LNT-", 4) == 0)) {
754 for (i = 0; i < 8; i++) {
755 if (ptr[i] == '\0' || !isxdigit (ptr[i]))
759 pdb_set_logon_time (pw_buf,
760 (time_t) strtol (ptr, NULL, 16),
765 pdb_set_logoff_time (pw_buf, get_time_t_max (), PDB_DEFAULT);
766 ptr = (uchar *) ENTRY_VAL (obj, NPF_LOGOFF_T);
767 if (ptr && *ptr && (StrnCaseCmp (ptr, "LOT-", 4) == 0)) {
771 for (i = 0; i < 8; i++) {
772 if (ptr[i] == '\0' || !isxdigit (ptr[i]))
776 pdb_set_logoff_time (pw_buf,
777 (time_t) strtol (ptr, NULL, 16),
782 pdb_set_kickoff_time (pw_buf, get_time_t_max (), PDB_DEFAULT);
783 ptr = (uchar *) ENTRY_VAL (obj, NPF_KICK_T);
784 if (ptr && *ptr && (StrnCaseCmp (ptr, "KOT-", 4) == 0)) {
788 for (i = 0; i < 8; i++) {
789 if (ptr[i] == '\0' || !isxdigit (ptr[i]))
793 pdb_set_kickoff_time (pw_buf,
794 (time_t) strtol (ptr, NULL, 16),
799 pdb_set_pass_last_set_time (pw_buf, (time_t) 0, PDB_DEFAULT);
800 ptr = (uchar *) ENTRY_VAL (obj, NPF_PWDLSET_T);
801 if (ptr && *ptr && (StrnCaseCmp (ptr, "LCT-", 4) == 0)) {
805 for (i = 0; i < 8; i++) {
806 if (ptr[i] == '\0' || !isxdigit (ptr[i]))
810 pdb_set_pass_last_set_time (pw_buf,
811 (time_t) strtol (ptr,
818 pdb_set_pass_can_change_time (pw_buf, (time_t) 0, PDB_DEFAULT);
819 ptr = (uchar *) ENTRY_VAL (obj, NPF_PWDCCHG_T);
820 if (ptr && *ptr && (StrnCaseCmp (ptr, "CCT-", 4) == 0)) {
824 for (i = 0; i < 8; i++) {
825 if (ptr[i] == '\0' || !isxdigit (ptr[i]))
829 pdb_set_pass_can_change_time (pw_buf,
830 (time_t) strtol (ptr,
837 pdb_set_pass_must_change_time (pw_buf, get_time_t_max (), PDB_DEFAULT); /* Password never expires. */
838 ptr = (uchar *) ENTRY_VAL (obj, NPF_PWDMCHG_T);
839 if (ptr && *ptr && (StrnCaseCmp (ptr, "MCT-", 4) == 0)) {
843 for (i = 0; i < 8; i++) {
844 if (ptr[i] == '\0' || !isxdigit (ptr[i]))
848 pdb_set_pass_must_change_time (pw_buf,
849 (time_t) strtol (ptr,
857 pdb_set_username (pw_buf, ENTRY_VAL (obj, NPF_NAME), PDB_SET);
858 pdb_set_domain (pw_buf, lp_workgroup (), PDB_DEFAULT);
859 /* pdb_set_nt_username() -- cant set it here... */
861 get_single_attribute (obj, NPF_FULL_NAME, full_name,
864 unix_to_dos (full_name, True);
866 pdb_set_fullname (pw_buf, full_name, PDB_SET);
868 pdb_set_acct_ctrl (pw_buf, pdb_decode_acct_ctrl (ENTRY_VAL (obj,
871 get_single_attribute (obj, NPF_ACCT_DESC, acct_desc,
874 unix_to_dos (acct_desc, True);
876 pdb_set_acct_desc (pw_buf, acct_desc, PDB_SET);
878 pdb_set_workstations (pw_buf, ENTRY_VAL (obj, NPF_WORKSTATIONS), PDB_SET);
879 pdb_set_munged_dial (pw_buf, NULL, PDB_DEFAULT);
881 pdb_set_uid (pw_buf, atoi (ENTRY_VAL (obj, NPF_UID)), PDB_SET);
882 pdb_set_gid (pw_buf, atoi (ENTRY_VAL (obj, NPF_SMB_GRPID)), PDB_SET);
883 pdb_set_user_sid_from_rid (pw_buf,
884 atoi (ENTRY_VAL (obj, NPF_USER_RID)), PDB_SET);
885 pdb_set_group_sid_from_rid (pw_buf,
886 atoi (ENTRY_VAL (obj, NPF_GROUP_RID)), PDB_SET);
888 /* values, must exist for user */
889 if (!(pdb_get_acct_ctrl (pw_buf) & ACB_WSTRUST)) {
891 get_single_attribute (obj, NPF_HOME_DIR, home_dir,
893 if (!(home_dir && *home_dir)) {
894 pstrcpy (home_dir, lp_logon_home ());
895 pdb_set_homedir (pw_buf, home_dir, PDB_DEFAULT);
897 pdb_set_homedir (pw_buf, home_dir, PDB_SET);
899 get_single_attribute (obj, NPF_DIR_DRIVE, home_drive,
901 if (!(home_drive && *home_drive)) {
902 pstrcpy (home_drive, lp_logon_drive ());
903 pdb_set_dir_drive (pw_buf, home_drive, PDB_DEFAULT);
905 pdb_set_dir_drive (pw_buf, home_drive, PDB_SET);
907 get_single_attribute (obj, NPF_LOGON_SCRIPT, logon_script,
909 if (!(logon_script && *logon_script)) {
910 pstrcpy (logon_script, lp_logon_script ());
911 pdb_set_logon_script (pw_buf, logon_script, PDB_DEFAULT);
913 pdb_set_logon_script (pw_buf, logon_script, PDB_SET);
915 get_single_attribute (obj, NPF_PROFILE_PATH, profile_path,
917 if (!(profile_path && *profile_path)) {
918 pstrcpy (profile_path, lp_logon_path ());
919 pdb_set_profile_path (pw_buf, profile_path, PDB_DEFAULT);
921 pdb_set_profile_path (pw_buf, profile_path, PDB_SET);
924 /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
925 pdb_set_group_sid_from_rid (pw_buf, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
928 /* Check the lanman password column. */
929 ptr = (char *) ENTRY_VAL (obj, NPF_LMPWD);
930 if (!pdb_set_lanman_passwd (pw_buf, NULL, PDB_DEFAULT))
933 if (!strncasecmp (ptr, "NO PASSWORD", 11)) {
934 pdb_set_acct_ctrl (pw_buf,
935 pdb_get_acct_ctrl (pw_buf) | ACB_PWNOTREQ, PDB_SET);
937 if (strlen (ptr) != 32 || !pdb_gethexpwd (ptr, smbpwd)) {
938 DEBUG (0, ("malformed LM pwd entry: %s.\n",
939 pdb_get_username (pw_buf)));
942 if (!pdb_set_lanman_passwd (pw_buf, smbpwd, PDB_SET))
946 /* Check the NT password column. */
947 ptr = ENTRY_VAL (obj, NPF_NTPWD);
948 if (!pdb_set_nt_passwd (pw_buf, NULL, PDB_DEFAULT))
951 if (!(pdb_get_acct_ctrl (pw_buf) & ACB_PWNOTREQ) &&
952 strncasecmp (ptr, "NO PASSWORD", 11)) {
953 if (strlen (ptr) != 32 || !pdb_gethexpwd (ptr, smbntpwd)) {
954 DEBUG (0, ("malformed NT pwd entry:\
955 uid = %d.\n", pdb_get_uid (pw_buf)));
958 if (!pdb_set_nt_passwd (pw_buf, smbntpwd, PDB_SET))
962 pdb_set_unknown_3 (pw_buf, 0xffffff, PDB_DEFAULT); /* don't know */
963 pdb_set_logon_divs (pw_buf, 168, PDB_DEFAULT); /* hours per week */
965 if ((hours_len = ENTRY_LEN (obj, NPF_HOURS)) == 21) {
966 memcpy (hours, ENTRY_VAL (obj, NPF_HOURS), hours_len);
968 hours_len = 21; /* 21 times 8 bits = 168 */
969 /* available at all hours */
970 memset (hours, 0xff, hours_len);
972 pdb_set_hours_len (pw_buf, hours_len, PDB_SET);
973 pdb_set_hours (pw_buf, hours, PDB_SET);
975 pdb_set_unknown_5 (pw_buf, 0x00020000, PDB_DEFAULT); /* don't know */
976 pdb_set_unknown_6 (pw_buf, 0x000004ec, PDB_DEFAULT); /* don't know */
981 /************************************************************************
982 makes a struct sam_passwd from a NIS+ result.
983 ************************************************************************/
984 static BOOL make_sam_from_nisresult (SAM_ACCOUNT * pw_buf,
985 const nis_result * result)
987 if (pw_buf == NULL || result == NULL)
990 if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND) {
991 DEBUG (0, ("NIS+ lookup failure: %s\n",
992 nis_sperrno (result->status)));
996 /* User not found. */
997 if (NIS_RES_NUMOBJ (result) <= 0) {
998 DEBUG (10, ("user not found in NIS+\n"));
1002 if (NIS_RES_NUMOBJ (result) > 1) {
1004 ("WARNING: Multiple entries for user in NIS+ table!\n"));
1007 /* Grab the first hit. */
1008 return make_sam_from_nisp_object (pw_buf,
1009 &NIS_RES_OBJECT (result)[0]);
1012 /*************************************************************************
1013 sets a NIS+ attribute
1014 *************************************************************************/
1015 static void set_single_attribute (nis_object * new_obj, int col,
1016 const char *val, int len, int flags)
1018 if (new_obj == NULL)
1021 ENTRY_VAL (new_obj, col) = val;
1022 ENTRY_LEN (new_obj, col) = len + 1;
1025 new_obj->EN_data.en_cols.en_cols_val[col].ec_flags = flags;
1029 /***************************************************************
1030 copy or modify nis object. this object is used to add or update
1031 nisplus table entry.
1032 ****************************************************************/
1033 static BOOL init_nisp_from_sam (nis_object * obj, const SAM_ACCOUNT * sampass,
1037 * Fill nis_object for entry add or update.
1038 * if we are updateing, we have to find out differences and set
1039 * EN_MODIFIED flag. also set need_to_modify to trigger
1040 * nis_modify_entry() call in pdb_update_sam_account().
1044 * if (modify) get data from nis_object, compare and store if
1045 * different + set EN_MODIFIED and need_to_modify
1049 BOOL need_to_modify = False;
1050 const char *name = pdb_get_username (sampass); /* from SAM */
1052 /* these must be static or allocate and free entry columns! */
1053 static fstring uid; /* from SAM */
1054 static fstring user_rid; /* from SAM */
1055 static fstring gid; /* from SAM */
1056 static fstring group_rid; /* from SAM */
1057 char *acb; /* from SAM */
1058 static fstring smb_passwd; /* from SAM */
1059 static fstring smb_nt_passwd; /* from SAM */
1060 static fstring logon_t; /* from SAM */
1061 static fstring logoff_t; /* from SAM */
1062 static fstring kickoff_t; /* from SAM */
1063 static fstring pwdlset_t; /* from SAM */
1064 static fstring pwdlchg_t; /* from SAM */
1065 static fstring pwdmchg_t; /* from SAM */
1066 static fstring full_name; /* from SAM */
1067 static fstring acct_desc; /* from SAM */
1068 static char empty[1]; /* just an empty string */
1070 slprintf (uid, sizeof (uid) - 1, "%u", pdb_get_uid (sampass));
1071 slprintf (user_rid, sizeof (user_rid) - 1, "%u",
1072 pdb_get_user_rid (sampass) ? pdb_get_user_rid (sampass) :
1073 fallback_pdb_uid_to_user_rid (pdb_get_uid (sampass)));
1074 slprintf (gid, sizeof (gid) - 1, "%u", pdb_get_gid (sampass));
1080 rid = pdb_get_group_rid (sampass);
1083 if (pdb_getgrgid(&map, pdb_get_gid (sampass),
1084 MAPPING_WITHOUT_PRIV)) {
1085 if (!sid_peek_check_rid
1086 (get_global_sam_sid (), &map.sid, &rid))
1089 rid = pdb_gid_to_group_rid (pdb_get_gid
1093 slprintf (group_rid, sizeof (group_rid) - 1, "%u", rid);
1096 acb = pdb_encode_acct_ctrl (pdb_get_acct_ctrl (sampass),
1097 NEW_PW_FORMAT_SPACE_PADDED_LEN);
1098 pdb_sethexpwd (smb_passwd, pdb_get_lanman_passwd (sampass),
1099 pdb_get_acct_ctrl (sampass));
1100 pdb_sethexpwd (smb_nt_passwd, pdb_get_nt_passwd (sampass),
1101 pdb_get_acct_ctrl (sampass));
1102 slprintf (logon_t, 13, "LNT-%08X",
1103 (uint32) pdb_get_logon_time (sampass));
1104 slprintf (logoff_t, 13, "LOT-%08X",
1105 (uint32) pdb_get_logoff_time (sampass));
1106 slprintf (kickoff_t, 13, "KOT-%08X",
1107 (uint32) pdb_get_kickoff_time (sampass));
1108 slprintf (pwdlset_t, 13, "LCT-%08X",
1109 (uint32) pdb_get_pass_last_set_time (sampass));
1110 slprintf (pwdlchg_t, 13, "CCT-%08X",
1111 (uint32) pdb_get_pass_can_change_time (sampass));
1112 slprintf (pwdmchg_t, 13, "MCT-%08X",
1113 (uint32) pdb_get_pass_must_change_time (sampass));
1114 safe_strcpy (full_name, pdb_get_fullname (sampass),
1115 sizeof (full_name) - 1);
1116 safe_strcpy (acct_desc, pdb_get_acct_desc (sampass),
1117 sizeof (acct_desc) - 1);
1121 /* Not sure what to do with these guys. -tpot */
1123 dos_to_unix (full_name, True);
1124 dos_to_unix (acct_desc, True);
1130 if (strcmp (ENTRY_VAL (old, NPF_NAME), name)) {
1131 need_to_modify = True;
1132 set_single_attribute (obj, NPF_NAME, name,
1133 strlen (name), EN_MODIFIED);
1138 if (pdb_get_uid (sampass) != -1) {
1139 if (!ENTRY_VAL (old, NPF_UID)
1140 || strcmp (ENTRY_VAL (old, NPF_UID), uid)) {
1141 need_to_modify = True;
1142 set_single_attribute (obj, NPF_UID, uid,
1149 if (pdb_get_user_rid (sampass)) {
1150 if (!ENTRY_VAL (old, NPF_USER_RID) ||
1151 strcmp (ENTRY_VAL (old, NPF_USER_RID),
1153 need_to_modify = True;
1154 set_single_attribute (obj, NPF_USER_RID,
1162 if (pdb_get_gid (sampass) != -1) {
1163 if (!ENTRY_VAL (old, NPF_SMB_GRPID) ||
1164 strcmp (ENTRY_VAL (old, NPF_SMB_GRPID), gid)) {
1165 need_to_modify = True;
1166 set_single_attribute (obj, NPF_SMB_GRPID, gid,
1173 if (pdb_get_group_rid (sampass)) {
1174 if (!ENTRY_VAL (old, NPF_GROUP_RID) ||
1175 strcmp (ENTRY_VAL (old, NPF_GROUP_RID),
1177 need_to_modify = True;
1178 set_single_attribute (obj, NPF_GROUP_RID,
1186 if (!ENTRY_VAL (old, NPF_ACB) ||
1187 strcmp (ENTRY_VAL (old, NPF_ACB), acb)) {
1188 need_to_modify = True;
1189 set_single_attribute (obj, NPF_ACB, acb, strlen (acb),
1194 if (!ENTRY_VAL (old, NPF_LMPWD) ||
1195 strcmp (ENTRY_VAL (old, NPF_LMPWD), smb_passwd)) {
1196 need_to_modify = True;
1197 set_single_attribute (obj, NPF_LMPWD, smb_passwd,
1198 strlen (smb_passwd),
1199 EN_CRYPT | EN_MODIFIED);
1203 if (!ENTRY_VAL (old, NPF_NTPWD) ||
1204 strcmp (ENTRY_VAL (old, NPF_NTPWD), smb_nt_passwd)) {
1205 need_to_modify = True;
1206 set_single_attribute (obj, NPF_NTPWD, smb_nt_passwd,
1207 strlen (smb_nt_passwd),
1208 EN_CRYPT | EN_MODIFIED);
1212 if (pdb_get_logon_time (sampass) &&
1213 (!ENTRY_VAL (old, NPF_LOGON_T) ||
1214 strcmp (ENTRY_VAL (old, NPF_LOGON_T), logon_t))) {
1215 need_to_modify = True;
1216 set_single_attribute (obj, NPF_LOGON_T, logon_t,
1217 strlen (logon_t), EN_MODIFIED);
1221 if (pdb_get_logoff_time (sampass) &&
1222 (!ENTRY_VAL (old, NPF_LOGOFF_T) ||
1223 strcmp (ENTRY_VAL (old, NPF_LOGOFF_T), logoff_t))) {
1224 need_to_modify = True;
1225 set_single_attribute (obj, NPF_LOGOFF_T, logoff_t,
1226 strlen (logoff_t), EN_MODIFIED);
1230 if (pdb_get_kickoff_time (sampass) &&
1231 (!ENTRY_VAL (old, NPF_KICK_T) ||
1232 strcmp (ENTRY_VAL (old, NPF_KICK_T), kickoff_t))) {
1233 need_to_modify = True;
1234 set_single_attribute (obj, NPF_KICK_T, kickoff_t,
1240 if (pdb_get_pass_last_set_time (sampass) &&
1241 (!ENTRY_VAL (old, NPF_PWDLSET_T) ||
1242 strcmp (ENTRY_VAL (old, NPF_PWDLSET_T), pwdlset_t))) {
1243 need_to_modify = True;
1244 set_single_attribute (obj, NPF_PWDLSET_T, pwdlset_t,
1250 if (pdb_get_pass_can_change_time (sampass) &&
1251 (!ENTRY_VAL (old, NPF_PWDCCHG_T) ||
1252 strcmp (ENTRY_VAL (old, NPF_PWDCCHG_T), pwdlchg_t))) {
1253 need_to_modify = True;
1254 set_single_attribute (obj, NPF_PWDCCHG_T, pwdlchg_t,
1260 if (pdb_get_pass_must_change_time (sampass) &&
1261 (!ENTRY_VAL (old, NPF_PWDMCHG_T) ||
1262 strcmp (ENTRY_VAL (old, NPF_PWDMCHG_T), pwdmchg_t))) {
1263 need_to_modify = True;
1264 set_single_attribute (obj, NPF_PWDMCHG_T, pwdmchg_t,
1270 /* must support set, unset and change */
1271 if ((pdb_get_fullname (sampass) &&
1272 !ENTRY_VAL (old, NPF_FULL_NAME)) ||
1273 (ENTRY_VAL (old, NPF_FULL_NAME) &&
1274 !pdb_get_fullname (sampass)) ||
1275 (ENTRY_VAL (old, NPF_FULL_NAME) &&
1276 pdb_get_fullname (sampass) &&
1277 strcmp (ENTRY_VAL (old, NPF_FULL_NAME), full_name))) {
1278 need_to_modify = True;
1279 set_single_attribute (obj, NPF_FULL_NAME, full_name,
1285 /* must support set, unset and change */
1286 if ((pdb_get_homedir (sampass) &&
1287 !ENTRY_VAL (old, NPF_HOME_DIR)) ||
1288 (ENTRY_VAL (old, NPF_HOME_DIR) &&
1289 !pdb_get_homedir (sampass)) ||
1290 (ENTRY_VAL (old, NPF_HOME_DIR) &&
1291 pdb_get_homedir (sampass) &&
1292 strcmp (ENTRY_VAL (old, NPF_HOME_DIR),
1293 pdb_get_homedir (sampass)))) {
1294 need_to_modify = True;
1295 set_single_attribute (obj, NPF_HOME_DIR,
1296 pdb_get_homedir (sampass),
1297 strlen (pdb_get_homedir
1303 /* must support set, unset and change */
1304 if ((pdb_get_dir_drive (sampass) &&
1305 !ENTRY_VAL (old, NPF_DIR_DRIVE)) ||
1306 (ENTRY_VAL (old, NPF_DIR_DRIVE) &&
1307 !pdb_get_dir_drive (sampass)) ||
1308 (ENTRY_VAL (old, NPF_DIR_DRIVE) &&
1309 pdb_get_dir_drive (sampass) &&
1310 strcmp (ENTRY_VAL (old, NPF_DIR_DRIVE),
1311 pdb_get_dir_drive (sampass)))) {
1312 need_to_modify = True;
1313 set_single_attribute (obj, NPF_DIR_DRIVE,
1314 pdb_get_dir_drive (sampass),
1315 strlen (pdb_get_dir_drive
1321 /* must support set, unset and change */
1322 if (((pdb_get_logon_script (sampass) &&
1323 !ENTRY_VAL (old, NPF_LOGON_SCRIPT)) ||
1324 ((ENTRY_VAL (old, NPF_LOGON_SCRIPT) &&
1325 (!pdb_get_logon_script (sampass)))) ||
1326 ((ENTRY_VAL (old, NPF_LOGON_SCRIPT) &&
1327 pdb_get_logon_script (sampass) &&
1328 strcmp (ENTRY_VAL (old, NPF_LOGON_SCRIPT),
1329 pdb_get_logon_script (sampass)))))) {
1330 need_to_modify = True;
1331 set_single_attribute (obj, NPF_LOGON_SCRIPT,
1332 pdb_get_logon_script (sampass),
1333 strlen (pdb_get_logon_script
1339 /* must support set, unset and change */
1340 if ((pdb_get_profile_path (sampass) &&
1341 !ENTRY_VAL (old, NPF_PROFILE_PATH)) ||
1342 (ENTRY_VAL (old, NPF_PROFILE_PATH) &&
1343 !pdb_get_profile_path (sampass)) ||
1344 (ENTRY_VAL (old, NPF_PROFILE_PATH) &&
1345 pdb_get_profile_path (sampass) &&
1346 strcmp (ENTRY_VAL (old, NPF_PROFILE_PATH),
1347 pdb_get_profile_path (sampass)))) {
1348 need_to_modify = True;
1349 set_single_attribute (obj, NPF_PROFILE_PATH,
1350 pdb_get_profile_path (sampass),
1351 strlen (pdb_get_profile_path
1357 /* must support set, unset and change */
1358 if ((pdb_get_acct_desc (sampass) &&
1359 !ENTRY_VAL (old, NPF_ACCT_DESC)) ||
1360 (ENTRY_VAL (old, NPF_ACCT_DESC) &&
1361 !pdb_get_acct_desc (sampass)) ||
1362 (ENTRY_VAL (old, NPF_ACCT_DESC) &&
1363 pdb_get_acct_desc (sampass) &&
1364 strcmp (ENTRY_VAL (old, NPF_ACCT_DESC), acct_desc))) {
1365 need_to_modify = True;
1366 set_single_attribute (obj, NPF_ACCT_DESC, acct_desc,
1372 /* must support set, unset and change */
1373 if ((pdb_get_workstations (sampass) &&
1374 !ENTRY_VAL (old, NPF_WORKSTATIONS)) ||
1375 (ENTRY_VAL (old, NPF_WORKSTATIONS) &&
1376 !pdb_get_workstations (sampass)) ||
1377 (ENTRY_VAL (old, NPF_WORKSTATIONS) &&
1378 (pdb_get_workstations (sampass)) &&
1379 strcmp (ENTRY_VAL (old, NPF_WORKSTATIONS),
1380 pdb_get_workstations (sampass)))) {
1381 need_to_modify = True;
1382 set_single_attribute (obj, NPF_WORKSTATIONS,
1383 pdb_get_workstations (sampass),
1384 strlen (pdb_get_workstations
1390 if ((pdb_get_hours_len (sampass) !=
1391 ENTRY_LEN (old, NPF_HOURS))
1392 || memcmp (pdb_get_hours (sampass),
1393 ENTRY_VAL (old, NPF_HOURS), ENTRY_LEN (old,
1396 need_to_modify = True;
1397 /* set_single_attribute will add 1 for len ... */
1398 set_single_attribute (obj, NPF_HOURS,
1399 pdb_get_hours (sampass),
1400 pdb_get_hours_len (sampass) - 1,
1404 const char *homedir, *dirdrive, *logon_script, *profile_path,
1407 *empty = '\0'; /* empty string */
1409 set_single_attribute (obj, NPF_NAME, name, strlen (name), 0);
1410 set_single_attribute (obj, NPF_UID, uid, strlen (uid), 0);
1411 set_single_attribute (obj, NPF_USER_RID, user_rid,
1412 strlen (user_rid), 0);
1413 set_single_attribute (obj, NPF_SMB_GRPID, gid, strlen (gid),
1415 set_single_attribute (obj, NPF_GROUP_RID, group_rid,
1416 strlen (group_rid), 0);
1417 set_single_attribute (obj, NPF_ACB, acb, strlen (acb), 0);
1418 set_single_attribute (obj, NPF_LMPWD, smb_passwd,
1419 strlen (smb_passwd), EN_CRYPT);
1420 set_single_attribute (obj, NPF_NTPWD, smb_nt_passwd,
1421 strlen (smb_nt_passwd), EN_CRYPT);
1422 set_single_attribute (obj, NPF_LOGON_T, logon_t,
1423 strlen (logon_t), 0);
1424 set_single_attribute (obj, NPF_LOGOFF_T, logoff_t,
1425 strlen (logoff_t), 0);
1426 set_single_attribute (obj, NPF_KICK_T, kickoff_t,
1427 strlen (kickoff_t), 0);
1428 set_single_attribute (obj, NPF_PWDLSET_T, pwdlset_t,
1429 strlen (pwdlset_t), 0);
1430 set_single_attribute (obj, NPF_PWDCCHG_T, pwdlchg_t,
1431 strlen (pwdlchg_t), 0);
1432 set_single_attribute (obj, NPF_PWDMCHG_T, pwdmchg_t,
1433 strlen (pwdmchg_t), 0);
1434 set_single_attribute (obj, NPF_FULL_NAME,
1435 full_name, strlen (full_name), 0);
1437 if (!(homedir = pdb_get_homedir (sampass)))
1440 set_single_attribute (obj, NPF_HOME_DIR,
1441 homedir, strlen (homedir), 0);
1443 if (!(dirdrive = pdb_get_dir_drive (sampass)))
1446 set_single_attribute (obj, NPF_DIR_DRIVE,
1447 dirdrive, strlen (dirdrive), 0);
1449 if (!(logon_script = pdb_get_logon_script (sampass)))
1450 logon_script = empty;
1452 set_single_attribute (obj, NPF_LOGON_SCRIPT,
1453 logon_script, strlen (logon_script), 0);
1455 if (!(profile_path = pdb_get_profile_path (sampass)))
1456 profile_path = empty;
1458 set_single_attribute (obj, NPF_PROFILE_PATH,
1459 profile_path, strlen (profile_path), 0);
1461 set_single_attribute (obj, NPF_ACCT_DESC,
1462 acct_desc, strlen (acct_desc), 0);
1464 if (!(workstations = pdb_get_workstations (sampass)))
1465 workstations = empty;
1467 set_single_attribute (obj, NPF_WORKSTATIONS,
1468 workstations, strlen (workstations), 0);
1470 /* set_single_attribute will add 1 for len ... */
1471 set_single_attribute (obj, NPF_HOURS,
1472 pdb_get_hours (sampass),
1473 pdb_get_hours_len (sampass) - 1, 0);
1476 return need_to_modify;
1479 /***************************************************************
1480 calls nis_list, returns results.
1481 ****************************************************************/
1482 static nis_result *nisp_get_nis_list (const char *nisname, unsigned int flags)
1488 flags = FOLLOW_LINKS | FOLLOW_PATH | EXPAND_NAME |
1491 for (i = 0; i < 2; i++) {
1492 alarm (60); /* hopefully ok for long searches */
1493 result = nis_list (nisname, flags, NULL, NULL);
1496 CatchSignal (SIGALRM, SIGNAL_CAST SIG_DFL);
1498 if (!(flags & MASTER_ONLY) && NIS_RES_NUMOBJ (result) <= 0) {
1499 /* nis replicas are not in sync perhaps?
1500 * this can happen, if account was just added.
1502 DEBUG (10, ("will try master only\n"));
1503 nis_freeresult (result);
1504 flags |= MASTER_ONLY;
1511 static void free_private_data(void **vp)
1513 struct nisplus_private_info **private = (struct nisplus_private_info **)vp;
1515 if ((*private)->result) {
1516 nis_freeresult ((*private)->result);
1521 /* No need to free any further, as it is talloc()ed */
1524 NTSTATUS pdb_init_nisplussam (PDB_CONTEXT * pdb_context,
1525 PDB_METHODS ** pdb_method, const char *location)
1528 struct nisplus_private_info *private = malloc (sizeof (struct nisplus_private_info));
1530 ZERO_STRUCT(private);
1531 p->location = talloc_strdup(pdb_context->mem_ctx, location);
1533 if (!NT_STATUS_IS_OK
1535 make_pdb_methods (pdb_context->mem_ctx, pdb_method))) {
1539 (*pdb_method)->name = "nisplussam";
1541 /* Functions your pdb module doesn't provide should be set
1544 (*pdb_method)->setsampwent = nisplussam_setsampwent;
1545 (*pdb_method)->endsampwent = nisplussam_endsampwent;
1546 (*pdb_method)->getsampwent = nisplussam_getsampwent;
1547 (*pdb_method)->getsampwnam = nisplussam_getsampwnam;
1548 (*pdb_method)->getsampwsid = nisplussam_getsampwsid;
1549 (*pdb_method)->add_sam_account = nisplussam_add_sam_account;
1550 (*pdb_method)->update_sam_account = nisplussam_update_sam_account;
1551 (*pdb_method)->delete_sam_account = nisplussam_delete_sam_account;
1552 (*pdb_method)->free_private_data = free_private_data;
1553 (*pdb_method)->private_data = private;
1555 return NT_STATUS_OK;
1559 NTSTATUS pdb_init_nisplussam (PDB_CONTEXT * c, PDB_METHODS ** m,
1562 DEBUG (0, ("nisplus sam not compiled in!\n"));
1563 return NT_STATUS_UNSUCCESSFUL;
1565 #endif /* WITH_NISPLUS_SAM */