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 BROKEN_NISPLUS_INCLUDE_FILES
30 * The following lines are needed due to buggy include files
31 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
32 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
33 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
34 * an enum in /usr/include/rpcsvc/nis.h.
42 #if defined(GROUP_OBJ)
48 #include <rpcsvc/nis.h>
50 /***************************************************************
52 the fields for the NIS+ table, generated from mknissmbpwtbl.sh, are:
81 ****************************************************************/
85 #define NPF_USER_RID 2
86 #define NPF_SMB_GRPID 3
87 #define NPF_GROUP_RID 4
92 #define NPF_LOGOFF_T 9
94 #define NPF_PWDLSET_T 11
95 #define NPF_PWDCCHG_T 12
96 #define NPF_PWDMCHG_T 13
97 #define NPF_FULL_NAME 14
98 #define NPF_HOME_DIR 15
99 #define NPF_DIR_DRIVE 16
100 #define NPF_LOGON_SCRIPT 17
101 #define NPF_PROFILE_PATH 18
102 #define NPF_ACCT_DESC 19
103 #define NPF_WORKSTATIONS 20
106 struct nisplus_private_info
{
112 static char *make_nisname_from_user_rid (uint32 rid
, char *pfile
);
113 static char *make_nisname_from_name (const char *user_name
, char *pfile
);
114 static void get_single_attribute (const nis_object
* new_obj
, int col
,
115 char *val
, int len
);;
116 static BOOL
make_sam_from_nisp_object (SAM_ACCOUNT
* pw_buf
,
117 const nis_object
* obj
);
118 static BOOL
make_sam_from_nisresult (SAM_ACCOUNT
* pw_buf
,
119 const nis_result
* result
);;
120 static void set_single_attribute (nis_object
* new_obj
, int col
,
121 const char *val
, int len
, int flags
);
122 static BOOL
init_nisp_from_sam (nis_object
* obj
, const SAM_ACCOUNT
* sampass
,
124 static nis_result
*nisp_get_nis_list (const char *nisname
,
127 /***************************************************************
128 Start enumeration of the passwd list.
129 ****************************************************************/
131 static NTSTATUS
nisplussam_setsampwent (struct pdb_methods
*methods
, BOOL update
)
133 struct nisplus_private_info
*private =
134 (struct nisplus_private_info
*) methods
->private_data
;
139 if ((sp
= strrchr (private->location
, '/')))
140 safe_strcpy (pfiletmp
, sp
+ 1, sizeof (pfiletmp
) - 1);
142 safe_strcpy (pfiletmp
, p
, sizeof (pfiletmp
) - 1);
143 safe_strcat (pfiletmp
, ".org_dir",
144 sizeof (pfiletmp
) - strlen (pfiletmp
) - 1);
146 pdb_endsampwent (); /* just in case */
147 global_nisp_ent
->result
= nisp_get_nis_list (pfiletmp
, 0);
148 global_nisp_ent
->enum_entry
= 0;
149 if (global_nisp_ent
->result
!= NULL
)
150 return NT_STATUS_UNSUCCESSFUL
;
155 /***************************************************************
156 End enumeration of the passwd list.
157 ****************************************************************/
159 static void nisplussam_endsampwent (struct pdb_methods
*methods
)
161 struct nisplus_private_info
*global_nisp_ent
=
162 (struct nisplus_private_info
*) methods
->private_data
;
163 if (global_nisp_ent
->result
)
164 nis_freeresult (global_nisp_ent
->result
);
165 global_nisp_ent
->result
= NULL
;
166 global_nisp_ent
->enum_entry
= 0;
169 /*****************************************************************
170 Get one SAM_ACCOUNT from the list (next in line)
171 *****************************************************************/
173 static NTSTATUS
nisplussam_getsampwent (struct pdb_methods
*methods
,
176 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
177 struct nisplus_private_info
*global_nisp_ent
=
178 (struct nisplus_private_info
*) methods
->private_data
;
179 int enum_entry
= (int) (global_nisp_ent
->enum_entry
);
180 nis_result
*result
= global_nisp_ent
->result
;
183 DEBUG (0, ("SAM_ACCOUNT is NULL.\n"));
187 if (result
== NULL
|| enum_entry
< 0 || enum_entry
>= (NIS_RES_NUMOBJ (result
) - 1)) {
191 if (!make_sam_from_nisp_object(user
, &NIS_RES_OBJECT (result
)[enum_entry
])) {
192 DEBUG (0, ("Bad SAM_ACCOUNT entry returned from NIS+!\n"));
195 (int) (global_nisp_ent
->enum_entry
)++;
200 /******************************************************************
201 Lookup a name in the SAM database
202 ******************************************************************/
204 static NTSTATUS
nisplussam_getsampwnam (struct pdb_methods
*methods
,
205 SAM_ACCOUNT
* user
, const char *sname
)
207 /* Static buffers we will return. */
208 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
209 nis_result
*result
= NULL
;
212 struct nisplus_private_info
*private =
213 (struct nisplus_private_info
*) methods
->private_data
;
215 if (!private->location
|| !(*private->location
)) {
216 DEBUG (0, ("No SMB password file set\n"));
219 if (strrchr (private->location
, '/'))
220 private->location
= strrchr (private->location
, '/') + 1;
222 slprintf (nisname
, sizeof (nisname
) - 1, "[name=%s],%s.org_dir",
223 sname
, private->location
);
224 DEBUG (10, ("search by nisname: %s\n", nisname
));
226 /* Search the table. */
228 if (!(result
= nisp_get_nis_list (nisname
, 0))) {
232 ret
= make_sam_from_nisresult (user
, result
);
233 nis_freeresult (result
);
235 if (ret
) nt_status
= NT_STATUS_OK
;
240 /***************************************************************************
242 **************************************************************************/
244 static NTSTATUS
nisplussam_getsampwrid (struct pdb_methods
*methods
,
245 SAM_ACCOUNT
* user
, uint32 rid
)
247 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
253 struct nisplus_private_info
*private =
254 (struct nisplus_private_info
*) methods
->private_data
;
256 if (!private->location
|| !(*private->location
)) {
257 DEBUG (0, ("no SMB password file set\n"));
261 if ((sp
= strrchr (private->location
, '/')))
262 safe_strcpy (pfiletmp
, sp
+ 1, sizeof (pfiletmp
) - 1);
264 safe_strcpy (pfiletmp
, private->location
, sizeof (pfiletmp
) - 1);
265 safe_strcat (pfiletmp
, ".org_dir",
266 sizeof (pfiletmp
) - strlen (pfiletmp
) - 1);
268 nisname
= make_nisname_from_user_rid (rid
, pfiletmp
);
270 DEBUG (10, ("search by rid: %s\n", nisname
));
272 /* Search the table. */
274 if (!(result
= nisp_get_nis_list (nisname
, 0))) {
278 ret
= make_sam_from_nisresult (user
, result
);
279 nis_freeresult (result
);
281 if (ret
) nt_status
= NT_STATUS_OK
;
286 static NTSTATUS
nisplussam_getsampwsid (struct pdb_methods
*methods
,
287 SAM_ACCOUNT
* user
, const DOM_SID
* sid
)
291 if (!sid_peek_check_rid (get_global_sam_sid (), sid
, &rid
))
292 return NT_STATUS_UNSUCCESSFUL
;
293 return nisplussam_getsampwrid (methods
, user
, rid
);
298 /***************************************************************************
300 ****************************************************************************/
302 static NTSTATUS
nisplussam_delete_sam_account (struct pdb_methods
*methods
,
305 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
308 nis_result
*result
, *delresult
;
310 struct nisplus_private_info
*private =
311 (struct nisplus_private_info
*) methods
->private_data
;
314 DEBUG (0, ("no SAM_ACCOUNT specified!\n"));
318 sname
= pdb_get_username (user
);
320 if (!private->location
|| !(*private->location
)) {
321 DEBUG (0, ("no SMB password file set\n"));
325 if (strrchr (private->location
, '/'))
326 private->location
= strrchr (private->location
, '/') + 1;
328 slprintf (nisname
, sizeof (nisname
) - 1, "[name=%s],%s.org_dir",
329 sname
, private->location
);
331 /* Search the table. */
333 if (!(result
= nisp_get_nis_list (nisname
,
334 MASTER_ONLY
| FOLLOW_LINKS
|
335 FOLLOW_PATH
| EXPAND_NAME
|
340 if (result
->status
!= NIS_SUCCESS
|| NIS_RES_NUMOBJ (result
) <= 0) {
341 /* User not found. */
342 DEBUG (0, ("user not found in NIS+\n"));
343 nis_freeresult (result
);
347 obj
= NIS_RES_OBJECT (result
);
348 slprintf (nisname
, sizeof (nisname
) - 1, "[name=%s],%s.%s", sname
,
349 obj
->zo_name
, obj
->zo_domain
);
351 DEBUG (10, ("removing name: %s\n", nisname
));
352 delresult
= nis_remove_entry (nisname
, obj
,
353 MASTER_ONLY
| REM_MULTIPLE
| ALL_RESULTS
354 | FOLLOW_PATH
| EXPAND_NAME
|
357 nis_freeresult (result
);
359 if (delresult
->status
!= NIS_SUCCESS
) {
360 DEBUG (0, ("NIS+ table update failed: %s %s\n",
361 nisname
, nis_sperrno (delresult
->status
)));
362 nis_freeresult (delresult
);
365 nis_freeresult (delresult
);
370 /***************************************************************************
371 Modifies an existing SAM_ACCOUNT
372 ****************************************************************************/
374 static NTSTATUS
nisplussam_update_sam_account (struct pdb_methods
*methods
,
375 SAM_ACCOUNT
* newpwd
)
377 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
378 nis_result
*result
, *addresult
;
383 struct nisplus_private_info
*private =
384 (struct nisplus_private_info
*) methods
->private_data
;
387 if (!private->location
|| !(*private->location
)) {
388 DEBUG (0, ("no SMB password file set\n"));
391 if (strrchr (private->location
, '/'))
392 private->location
= strrchr (private->location
, '/') + 1;
394 slprintf (nisname
, sizeof (nisname
) - 1, "[name=%s],%s.org_dir",
395 pdb_get_username (newpwd
), private->location
);
397 DEBUG (10, ("search by name: %s\n", nisname
));
399 /* Search the table. */
403 nisp_get_nis_list (nisname
,
404 MASTER_ONLY
| FOLLOW_LINKS
| FOLLOW_PATH
|
405 EXPAND_NAME
| HARD_LOOKUP
))) {
409 if (result
->status
!= NIS_SUCCESS
|| NIS_RES_NUMOBJ (result
) <= 0) {
410 /* User not found. */
411 DEBUG (0, ("user not found in NIS+\n"));
412 nis_freeresult (result
);
416 obj
= NIS_RES_OBJECT (result
);
417 DEBUG (6, ("entry found in %s\n", obj
->zo_domain
));
419 /* we must create new stub object with EN_MODIFIED flag.
420 this is because obj from result is going to be freed and
421 we do not want to break it or cause memory leaks or corruption.
424 memmove ((char *) &new_obj
, obj
, sizeof (new_obj
));
425 ta_maxcol
= obj
->TA_data
.ta_maxcol
;
427 if (!(ecol
= (entry_col
*) malloc (ta_maxcol
* sizeof (entry_col
)))) {
428 DEBUG (0, ("memory allocation failure\n"));
429 nis_freeresult (result
);
433 memmove ((char *) ecol
, obj
->EN_data
.en_cols
.en_cols_val
,
434 ta_maxcol
* sizeof (entry_col
));
435 new_obj
.EN_data
.en_cols
.en_cols_val
= ecol
;
436 new_obj
.EN_data
.en_cols
.en_cols_len
= ta_maxcol
;
438 if (init_nisp_from_sam (&new_obj
, newpwd
, obj
) == True
) {
439 slprintf (nisname
, sizeof (nisname
) - 1, "[name=%s],%s.%s",
440 pdb_get_username (newpwd
), private->location
, obj
->zo_domain
);
442 DEBUG (10, ("NIS+ table update: %s\n", nisname
));
444 nis_modify_entry (nisname
, &new_obj
,
445 MOD_SAMEOBJ
| FOLLOW_PATH
|
446 EXPAND_NAME
| HARD_LOOKUP
);
448 if (addresult
->status
!= NIS_SUCCESS
) {
449 DEBUG (0, ("NIS+ table update failed: %s %s\n",
450 nisname
, nis_sperrno (addresult
->status
)));
451 nis_freeresult (addresult
);
452 nis_freeresult (result
);
457 DEBUG (6, ("password changed\n"));
458 nis_freeresult (addresult
);
460 DEBUG (6, ("nothing to change!\n"));
464 nis_freeresult (result
);
469 /***************************************************************************
470 Adds an existing SAM_ACCOUNT
471 ****************************************************************************/
473 static NTSTATUS
nisplussam_add_sam_account (struct pdb_methods
*methods
,
474 SAM_ACCOUNT
* newpwd
)
476 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
481 nis_result
*result
= NULL
, *tblresult
= NULL
;
487 * 1. find user domain.
488 * a. try nis search in passwd.org_dir - if found use domain from result.
489 * b. try getpwnam. this may be needed if user is defined
490 * in /etc/passwd file (or elsewere) and not in passwd.org_dir.
491 * if found, use host default domain.
492 * c. exit with False - no such user.
495 * a. find smbpasswd table
496 * search pfile in user domain if not found, try host default
498 * b. smbpasswd domain is found, fill data and add entry.
500 * pfile should contain ONLY table name, org_dir will be concated.
501 * so, at first we will clear path prefix from pfile, and
502 * then we will use pfiletmp as playground to put together full
504 * such approach will make it possible to specify samba private dir
505 * AND still use NIS+ table. as all domain related data is normally
506 * stored in org_dir.DOMAIN, this should be ok do do.
509 pfile
= private->location
;
510 if (strrchr (pfile
, '/'))
511 pfile
= strrchr (pfile
, '/') + 1;
514 * Check if user is already there.
516 safe_strcpy (pfiletmp
, pfile
, sizeof (pfiletmp
) - 1);
517 safe_strcat (pfiletmp
, ".org_dir",
518 sizeof (pfiletmp
) - strlen (pfiletmp
) - 1);
520 if (pdb_get_username (newpwd
) != NULL
) {
521 nisname
= make_nisname_from_name (pdb_get_username (newpwd
),
529 nisp_get_nis_list (nisname
,
530 MASTER_ONLY
| FOLLOW_LINKS
| FOLLOW_PATH
|
531 EXPAND_NAME
| HARD_LOOKUP
))) {
534 if (result
->status
!= NIS_SUCCESS
&& result
->status
!= NIS_NOTFOUND
) {
535 DEBUG (3, ("nis_list failure: %s: %s\n",
536 nisname
, nis_sperrno (result
->status
)));
537 nis_freeresult (result
);
541 if (result
->status
== NIS_SUCCESS
&& NIS_RES_NUMOBJ (result
) > 0) {
542 DEBUG (3, ("User already exists in NIS+ password db: %s\n",
544 nis_freeresult (result
);
548 nis_freeresult (result
); /* no such user, free results */
551 * check for user in unix password database. we need this to get
552 * domain, where smbpasswd entry should be stored.
555 nisname
= make_nisname_from_name (pdb_get_username (newpwd
),
558 result
= nisp_get_nis_list (nisname
,
559 MASTER_ONLY
| FOLLOW_LINKS
| FOLLOW_PATH
|
560 EXPAND_NAME
| HARD_LOOKUP
);
562 if (result
->status
!= NIS_SUCCESS
|| NIS_RES_NUMOBJ (result
) <= 0) {
563 struct passwd
*passwd
;
565 DEBUG (3, ("nis_list failure: %s: %s\n",
566 nisname
, nis_sperrno (result
->status
)));
567 nis_freeresult (result
);
569 if (!(passwd
= getpwnam_alloc (pdb_get_username (newpwd
)))) {
570 /* no such user in system! */
573 passwd_free (&passwd
);
576 * user is defined, but not in passwd.org_dir.
580 safe_strcpy (pfiletmp
, pfile
, sizeof (pfiletmp
) - 1);
581 safe_strcat (pfiletmp
, ".",
582 sizeof (pfiletmp
) - strlen (pfiletmp
) - 1);
583 safe_strcat (pfiletmp
, NIS_RES_OBJECT (result
)->zo_domain
,
584 sizeof (pfiletmp
) - strlen (pfiletmp
) - 1);
585 nis_freeresult (result
); /* not needed any more */
587 tblresult
= nisp_get_nis_list (pfiletmp
,
588 MASTER_ONLY
| FOLLOW_LINKS
|
589 FOLLOW_PATH
| EXPAND_NAME
|
593 if (local_user
|| tblresult
->status
!= NIS_SUCCESS
) {
596 * smbpasswd table not found in user domain, fallback to
599 if (!local_user
) /* free previous failed search result */
600 nis_freeresult (tblresult
);
602 safe_strcpy (pfiletmp
, pfile
, sizeof (pfiletmp
) - 1);
603 safe_strcat (pfiletmp
, ".org_dir",
604 sizeof (pfiletmp
) - strlen (pfiletmp
) - 1);
605 tblresult
= nis_lookup (pfiletmp
, MASTER_ONLY
| FOLLOW_LINKS
|
606 FOLLOW_PATH
| EXPAND_NAME
|
608 if (tblresult
->status
!= NIS_SUCCESS
) {
609 /* still nothing. bail out */
610 nis_freeresult (tblresult
);
611 DEBUG (3, ("nis_lookup failure: %s\n",
612 nis_sperrno (tblresult
->status
)));
615 /* we need full name for nis_add_entry() */
616 safe_strcpy (pfiletmp
, pfile
, sizeof (pfiletmp
) - 1);
617 safe_strcat (pfiletmp
, ".",
618 sizeof (pfiletmp
) - strlen (pfiletmp
) - 1);
619 safe_strcat (pfiletmp
, NIS_RES_OBJECT (tblresult
)->zo_domain
,
620 sizeof (pfiletmp
) - strlen (pfiletmp
) - 1);
623 memset ((char *) &new_obj
, 0, sizeof (new_obj
));
624 /* fill entry headers */
625 /* we do not free these. */
626 new_obj
.zo_name
= NIS_RES_OBJECT (tblresult
)->zo_name
;
627 new_obj
.zo_owner
= NIS_RES_OBJECT (tblresult
)->zo_owner
;
628 new_obj
.zo_group
= NIS_RES_OBJECT (tblresult
)->zo_group
;
629 new_obj
.zo_domain
= NIS_RES_OBJECT (tblresult
)->zo_domain
;
631 new_obj
.zo_access
= NIS_RES_OBJECT (tblresult
)->zo_access
;
632 new_obj
.zo_ttl
= NIS_RES_OBJECT (tblresult
)->zo_ttl
;
634 new_obj
.zo_data
.zo_type
= ENTRY_OBJ
;
635 new_obj
.EN_data
.en_type
= NIS_RES_OBJECT (tblresult
)->TA_data
.ta_type
;
637 ta_maxcol
= NIS_RES_OBJECT (tblresult
)->TA_data
.ta_maxcol
;
639 if (!(ecol
= (entry_col
*) malloc (ta_maxcol
* sizeof (entry_col
)))) {
640 DEBUG (0, ("memory allocation failure\n"));
641 nis_freeresult (tblresult
);
645 memset ((char *) ecol
, 0, ta_maxcol
* sizeof (entry_col
));
646 new_obj
.EN_data
.en_cols
.en_cols_val
= ecol
;
647 new_obj
.EN_data
.en_cols
.en_cols_len
= ta_maxcol
;
649 init_nisp_from_sam (&new_obj
, newpwd
, NULL
);
651 DEBUG (10, ("add NIS+ entry: %s\n", nisname
));
652 result
= nis_add_entry (pfiletmp
, &new_obj
, 0);
654 free (ecol
); /* free allocated entry space */
656 if (result
->status
!= NIS_SUCCESS
) {
657 DEBUG (3, ("NIS+ table update failed: %s,%s\n",
658 nisname
, nis_sperrno (result
->status
)));
659 nis_freeresult (tblresult
);
660 nis_freeresult (result
);
664 nis_freeresult (tblresult
);
665 nis_freeresult (result
);
670 /***************************************************************
671 make_nisname_from_user_rid
672 ****************************************************************/
673 static char *make_nisname_from_user_rid (uint32 rid
, char *pfile
)
675 static pstring nisname
;
677 safe_strcpy (nisname
, "[user_rid=", sizeof (nisname
) - 1);
678 slprintf (nisname
, sizeof (nisname
) - 1, "%s%d", nisname
, rid
);
679 safe_strcat (nisname
, "],", sizeof (nisname
) - strlen (nisname
) - 1);
680 safe_strcat (nisname
, pfile
, sizeof (nisname
) - strlen (nisname
) - 1);
685 /***************************************************************
686 make_nisname_from_name
687 ****************************************************************/
688 static char *make_nisname_from_name (const char *user_name
, char *pfile
)
690 static pstring nisname
;
692 safe_strcpy (nisname
, "[name=", sizeof (nisname
) - 1);
693 safe_strcat (nisname
, user_name
,
694 sizeof (nisname
) - strlen (nisname
) - 1);
695 safe_strcat (nisname
, "],", sizeof (nisname
) - strlen (nisname
) - 1);
696 safe_strcat (nisname
, pfile
, sizeof (nisname
) - strlen (nisname
) - 1);
701 /*************************************************************************
702 gets a NIS+ attribute
703 *************************************************************************/
704 static void get_single_attribute (const nis_object
* new_obj
, int col
,
709 if (new_obj
== NULL
|| val
== NULL
)
712 entry_len
= ENTRY_LEN (new_obj
, col
);
713 if (len
> entry_len
) {
717 safe_strcpy (val
, ENTRY_VAL (new_obj
, col
), len
- 1);
720 /************************************************************************
721 makes a struct sam_passwd from a NIS+ object.
722 ************************************************************************/
723 static BOOL
make_sam_from_nisp_object (SAM_ACCOUNT
* pw_buf
,
724 const nis_object
* obj
)
727 pstring full_name
; /* this must be translated to dos code page */
728 pstring acct_desc
; /* this must be translated to dos code page */
729 pstring home_dir
; /* set default value from smb.conf for user */
730 pstring home_drive
; /* set default value from smb.conf for user */
731 pstring logon_script
; /* set default value from smb.conf for user */
732 pstring profile_path
; /* set default value from smb.conf for user */
735 unsigned char smbpwd
[16];
736 unsigned char smbntpwd
[16];
740 * time values. note: this code assumes 32bit time_t!
743 /* Don't change these timestamp settings without a good reason. They are
744 important for NT member server compatibility. */
746 pdb_set_logon_time (pw_buf
, (time_t) 0, PDB_DEFAULT
);
747 ptr
= (uchar
*) ENTRY_VAL (obj
, NPF_LOGON_T
);
748 if (ptr
&& *ptr
&& (StrnCaseCmp (ptr
, "LNT-", 4) == 0)) {
752 for (i
= 0; i
< 8; i
++) {
753 if (ptr
[i
] == '\0' || !isxdigit (ptr
[i
]))
757 pdb_set_logon_time (pw_buf
,
758 (time_t) strtol (ptr
, NULL
, 16),
763 pdb_set_logoff_time (pw_buf
, get_time_t_max (), PDB_DEFAULT
);
764 ptr
= (uchar
*) ENTRY_VAL (obj
, NPF_LOGOFF_T
);
765 if (ptr
&& *ptr
&& (StrnCaseCmp (ptr
, "LOT-", 4) == 0)) {
769 for (i
= 0; i
< 8; i
++) {
770 if (ptr
[i
] == '\0' || !isxdigit (ptr
[i
]))
774 pdb_set_logoff_time (pw_buf
,
775 (time_t) strtol (ptr
, NULL
, 16),
780 pdb_set_kickoff_time (pw_buf
, get_time_t_max (), PDB_DEFAULT
);
781 ptr
= (uchar
*) ENTRY_VAL (obj
, NPF_KICK_T
);
782 if (ptr
&& *ptr
&& (StrnCaseCmp (ptr
, "KOT-", 4) == 0)) {
786 for (i
= 0; i
< 8; i
++) {
787 if (ptr
[i
] == '\0' || !isxdigit (ptr
[i
]))
791 pdb_set_kickoff_time (pw_buf
,
792 (time_t) strtol (ptr
, NULL
, 16),
797 pdb_set_pass_last_set_time (pw_buf
, (time_t) 0, PDB_DEFAULT
);
798 ptr
= (uchar
*) ENTRY_VAL (obj
, NPF_PWDLSET_T
);
799 if (ptr
&& *ptr
&& (StrnCaseCmp (ptr
, "LCT-", 4) == 0)) {
803 for (i
= 0; i
< 8; i
++) {
804 if (ptr
[i
] == '\0' || !isxdigit (ptr
[i
]))
808 pdb_set_pass_last_set_time (pw_buf
,
809 (time_t) strtol (ptr
,
816 pdb_set_pass_can_change_time (pw_buf
, (time_t) 0, PDB_DEFAULT
);
817 ptr
= (uchar
*) ENTRY_VAL (obj
, NPF_PWDCCHG_T
);
818 if (ptr
&& *ptr
&& (StrnCaseCmp (ptr
, "CCT-", 4) == 0)) {
822 for (i
= 0; i
< 8; i
++) {
823 if (ptr
[i
] == '\0' || !isxdigit (ptr
[i
]))
827 pdb_set_pass_can_change_time (pw_buf
,
828 (time_t) strtol (ptr
,
835 pdb_set_pass_must_change_time (pw_buf
, get_time_t_max (), PDB_DEFAULT
); /* Password never expires. */
836 ptr
= (uchar
*) ENTRY_VAL (obj
, NPF_PWDMCHG_T
);
837 if (ptr
&& *ptr
&& (StrnCaseCmp (ptr
, "MCT-", 4) == 0)) {
841 for (i
= 0; i
< 8; i
++) {
842 if (ptr
[i
] == '\0' || !isxdigit (ptr
[i
]))
846 pdb_set_pass_must_change_time (pw_buf
,
847 (time_t) strtol (ptr
,
855 pdb_set_username (pw_buf
, ENTRY_VAL (obj
, NPF_NAME
), PDB_SET
);
856 pdb_set_domain (pw_buf
, lp_workgroup (), PDB_DEFAULT
);
857 /* pdb_set_nt_username() -- cant set it here... */
859 get_single_attribute (obj
, NPF_FULL_NAME
, full_name
,
862 unix_to_dos (full_name
, True
);
864 pdb_set_fullname (pw_buf
, full_name
, PDB_SET
);
866 pdb_set_acct_ctrl (pw_buf
, pdb_decode_acct_ctrl (ENTRY_VAL (obj
,
869 get_single_attribute (obj
, NPF_ACCT_DESC
, acct_desc
,
872 unix_to_dos (acct_desc
, True
);
874 pdb_set_acct_desc (pw_buf
, acct_desc
, PDB_SET
);
876 pdb_set_workstations (pw_buf
, ENTRY_VAL (obj
, NPF_WORKSTATIONS
), PDB_SET
);
877 pdb_set_munged_dial (pw_buf
, NULL
, PDB_DEFAULT
);
879 pdb_set_user_sid_from_rid (pw_buf
,
880 atoi (ENTRY_VAL (obj
, NPF_USER_RID
)), PDB_SET
);
881 pdb_set_group_sid_from_rid (pw_buf
,
882 atoi (ENTRY_VAL (obj
, NPF_GROUP_RID
)), PDB_SET
);
884 /* values, must exist for user */
885 if (!(pdb_get_acct_ctrl (pw_buf
) & ACB_WSTRUST
)) {
887 get_single_attribute (obj
, NPF_HOME_DIR
, home_dir
,
889 if (!(home_dir
&& *home_dir
)) {
890 pstrcpy (home_dir
, lp_logon_home ());
891 pdb_set_homedir (pw_buf
, home_dir
, PDB_DEFAULT
);
893 pdb_set_homedir (pw_buf
, home_dir
, PDB_SET
);
895 get_single_attribute (obj
, NPF_DIR_DRIVE
, home_drive
,
897 if (!(home_drive
&& *home_drive
)) {
898 pstrcpy (home_drive
, lp_logon_drive ());
899 pdb_set_dir_drive (pw_buf
, home_drive
, PDB_DEFAULT
);
901 pdb_set_dir_drive (pw_buf
, home_drive
, PDB_SET
);
903 get_single_attribute (obj
, NPF_LOGON_SCRIPT
, logon_script
,
905 if (!(logon_script
&& *logon_script
)) {
906 pstrcpy (logon_script
, lp_logon_script ());
907 pdb_set_logon_script (pw_buf
, logon_script
, PDB_DEFAULT
);
909 pdb_set_logon_script (pw_buf
, logon_script
, PDB_SET
);
911 get_single_attribute (obj
, NPF_PROFILE_PATH
, profile_path
,
913 if (!(profile_path
&& *profile_path
)) {
914 pstrcpy (profile_path
, lp_logon_path ());
915 pdb_set_profile_path (pw_buf
, profile_path
, PDB_DEFAULT
);
917 pdb_set_profile_path (pw_buf
, profile_path
, PDB_SET
);
920 /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
921 pdb_set_group_sid_from_rid (pw_buf
, DOMAIN_GROUP_RID_USERS
, PDB_DEFAULT
);
924 /* Check the lanman password column. */
925 ptr
= (char *) ENTRY_VAL (obj
, NPF_LMPWD
);
926 if (!pdb_set_lanman_passwd (pw_buf
, NULL
, PDB_DEFAULT
))
929 if (!strncasecmp (ptr
, "NO PASSWORD", 11)) {
930 pdb_set_acct_ctrl (pw_buf
,
931 pdb_get_acct_ctrl (pw_buf
) | ACB_PWNOTREQ
, PDB_SET
);
933 if (strlen (ptr
) != 32 || !pdb_gethexpwd (ptr
, smbpwd
)) {
934 DEBUG (0, ("malformed LM pwd entry: %s.\n",
935 pdb_get_username (pw_buf
)));
938 if (!pdb_set_lanman_passwd (pw_buf
, smbpwd
, PDB_SET
))
942 /* Check the NT password column. */
943 ptr
= ENTRY_VAL (obj
, NPF_NTPWD
);
944 if (!pdb_set_nt_passwd (pw_buf
, NULL
, PDB_DEFAULT
))
947 if (!(pdb_get_acct_ctrl (pw_buf
) & ACB_PWNOTREQ
) &&
948 strncasecmp (ptr
, "NO PASSWORD", 11)) {
949 if (strlen (ptr
) != 32 || !pdb_gethexpwd (ptr
, smbntpwd
)) {
950 DEBUG (0, ("malformed NT pwd entry:\ %s.\n",
951 pdb_get_username (pw_buf
)));
954 if (!pdb_set_nt_passwd (pw_buf
, smbntpwd
, PDB_SET
))
958 pdb_set_unknown_3 (pw_buf
, 0xffffff, PDB_DEFAULT
); /* don't know */
959 pdb_set_logon_divs (pw_buf
, 168, PDB_DEFAULT
); /* hours per week */
961 if ((hours_len
= ENTRY_LEN (obj
, NPF_HOURS
)) == 21) {
962 memcpy (hours
, ENTRY_VAL (obj
, NPF_HOURS
), hours_len
);
964 hours_len
= 21; /* 21 times 8 bits = 168 */
965 /* available at all hours */
966 memset (hours
, 0xff, hours_len
);
968 pdb_set_hours_len (pw_buf
, hours_len
, PDB_SET
);
969 pdb_set_hours (pw_buf
, hours
, PDB_SET
);
971 pdb_set_unknown_5 (pw_buf
, 0x00020000, PDB_DEFAULT
); /* don't know */
972 pdb_set_unknown_6 (pw_buf
, 0x000004ec, PDB_DEFAULT
); /* don't know */
977 /************************************************************************
978 makes a struct sam_passwd from a NIS+ result.
979 ************************************************************************/
980 static BOOL
make_sam_from_nisresult (SAM_ACCOUNT
* pw_buf
,
981 const nis_result
* result
)
983 if (pw_buf
== NULL
|| result
== NULL
)
986 if (result
->status
!= NIS_SUCCESS
&& result
->status
!= NIS_NOTFOUND
) {
987 DEBUG (0, ("NIS+ lookup failure: %s\n",
988 nis_sperrno (result
->status
)));
992 /* User not found. */
993 if (NIS_RES_NUMOBJ (result
) <= 0) {
994 DEBUG (10, ("user not found in NIS+\n"));
998 if (NIS_RES_NUMOBJ (result
) > 1) {
1000 ("WARNING: Multiple entries for user in NIS+ table!\n"));
1003 /* Grab the first hit. */
1004 return make_sam_from_nisp_object (pw_buf
,
1005 &NIS_RES_OBJECT (result
)[0]);
1008 /*************************************************************************
1009 sets a NIS+ attribute
1010 *************************************************************************/
1011 static void set_single_attribute (nis_object
* new_obj
, int col
,
1012 const char *val
, int len
, int flags
)
1014 if (new_obj
== NULL
)
1017 ENTRY_VAL (new_obj
, col
) = val
;
1018 ENTRY_LEN (new_obj
, col
) = len
+ 1;
1021 new_obj
->EN_data
.en_cols
.en_cols_val
[col
].ec_flags
= flags
;
1025 /***************************************************************
1026 copy or modify nis object. this object is used to add or update
1027 nisplus table entry.
1028 ****************************************************************/
1029 static BOOL
init_nisp_from_sam (nis_object
* obj
, const SAM_ACCOUNT
* sampass
,
1033 * Fill nis_object for entry add or update.
1034 * if we are updateing, we have to find out differences and set
1035 * EN_MODIFIED flag. also set need_to_modify to trigger
1036 * nis_modify_entry() call in pdb_update_sam_account().
1040 * if (modify) get data from nis_object, compare and store if
1041 * different + set EN_MODIFIED and need_to_modify
1045 BOOL need_to_modify
= False
;
1046 const char *name
= pdb_get_username (sampass
); /* from SAM */
1050 /* these must be static or allocate and free entry columns! */
1051 static fstring uid
; /* from SAM */
1052 static fstring user_rid
; /* from SAM */
1053 static fstring gid
; /* from SAM */
1054 static fstring group_rid
; /* from SAM */
1055 char *acb
; /* from SAM */
1056 static fstring smb_passwd
; /* from SAM */
1057 static fstring smb_nt_passwd
; /* from SAM */
1058 static fstring logon_t
; /* from SAM */
1059 static fstring logoff_t
; /* from SAM */
1060 static fstring kickoff_t
; /* from SAM */
1061 static fstring pwdlset_t
; /* from SAM */
1062 static fstring pwdlchg_t
; /* from SAM */
1063 static fstring pwdmchg_t
; /* from SAM */
1064 static fstring full_name
; /* from SAM */
1065 static fstring acct_desc
; /* from SAM */
1066 static char empty
[1]; /* just an empty string */
1068 if (!(u_rid
= pdb_get_user_rid (sampass
)))
1070 if (!(g_rid
= pdb_get_group_rid (sampass
)))
1073 slprintf (uid
, sizeof (uid
) - 1, "%u", fallback_pdb_user_rid_to_uid (u_rid
));
1074 slprintf (user_rid
, sizeof (user_rid
) - 1, "%u", u_rid
);
1075 slprintf (gid
, sizeof (gid
) - 1, "%u", fallback_pdb_group_rid_to_uid (g_rid
));
1076 slprintf (group_rid
, sizeof (group_rid
) - 1, "%u", g_rid
);
1078 acb
= pdb_encode_acct_ctrl (pdb_get_acct_ctrl (sampass
),
1079 NEW_PW_FORMAT_SPACE_PADDED_LEN
);
1080 pdb_sethexpwd (smb_passwd
, pdb_get_lanman_passwd (sampass
),
1081 pdb_get_acct_ctrl (sampass
));
1082 pdb_sethexpwd (smb_nt_passwd
, pdb_get_nt_passwd (sampass
),
1083 pdb_get_acct_ctrl (sampass
));
1084 slprintf (logon_t
, 13, "LNT-%08X",
1085 (uint32
) pdb_get_logon_time (sampass
));
1086 slprintf (logoff_t
, 13, "LOT-%08X",
1087 (uint32
) pdb_get_logoff_time (sampass
));
1088 slprintf (kickoff_t
, 13, "KOT-%08X",
1089 (uint32
) pdb_get_kickoff_time (sampass
));
1090 slprintf (pwdlset_t
, 13, "LCT-%08X",
1091 (uint32
) pdb_get_pass_last_set_time (sampass
));
1092 slprintf (pwdlchg_t
, 13, "CCT-%08X",
1093 (uint32
) pdb_get_pass_can_change_time (sampass
));
1094 slprintf (pwdmchg_t
, 13, "MCT-%08X",
1095 (uint32
) pdb_get_pass_must_change_time (sampass
));
1096 safe_strcpy (full_name
, pdb_get_fullname (sampass
),
1097 sizeof (full_name
) - 1);
1098 safe_strcpy (acct_desc
, pdb_get_acct_desc (sampass
),
1099 sizeof (acct_desc
) - 1);
1103 /* Not sure what to do with these guys. -tpot */
1105 dos_to_unix (full_name
, True
);
1106 dos_to_unix (acct_desc
, True
);
1112 if (strcmp (ENTRY_VAL (old
, NPF_NAME
), name
)) {
1113 need_to_modify
= True
;
1114 set_single_attribute (obj
, NPF_NAME
, name
,
1115 strlen (name
), EN_MODIFIED
);
1120 if (!ENTRY_VAL (old
, NPF_UID
) || strcmp (ENTRY_VAL (old
, NPF_UID
), uid
)) {
1121 need_to_modify
= True
;
1122 set_single_attribute (obj
, NPF_UID
, uid
, strlen (uid
), EN_MODIFIED
);
1126 if (!ENTRY_VAL (old
, NPF_USER_RID
) || strcmp (ENTRY_VAL (old
, NPF_USER_RID
), user_rid
)) {
1127 need_to_modify
= True
;
1128 set_single_attribute (obj
, NPF_USER_RID
, user_rid
, strlen (user_rid
), EN_MODIFIED
);
1132 if (!ENTRY_VAL (old
, NPF_SMB_GRPID
) || strcmp (ENTRY_VAL (old
, NPF_SMB_GRPID
), gid
)) {
1133 need_to_modify
= True
;
1134 set_single_attribute (obj
, NPF_SMB_GRPID
, gid
, strlen (gid
), EN_MODIFIED
);
1138 if (!ENTRY_VAL (old
, NPF_GROUP_RID
) || strcmp (ENTRY_VAL (old
, NPF_GROUP_RID
), group_rid
)) {
1139 need_to_modify
= True
;
1140 set_single_attribute (obj
, NPF_GROUP_RID
, group_rid
, strlen (group_rid
), EN_MODIFIED
);
1144 if (!ENTRY_VAL (old
, NPF_ACB
) ||
1145 strcmp (ENTRY_VAL (old
, NPF_ACB
), acb
)) {
1146 need_to_modify
= True
;
1147 set_single_attribute (obj
, NPF_ACB
, acb
, strlen (acb
),
1152 if (!ENTRY_VAL (old
, NPF_LMPWD
) ||
1153 strcmp (ENTRY_VAL (old
, NPF_LMPWD
), smb_passwd
)) {
1154 need_to_modify
= True
;
1155 set_single_attribute (obj
, NPF_LMPWD
, smb_passwd
,
1156 strlen (smb_passwd
),
1157 EN_CRYPT
| EN_MODIFIED
);
1161 if (!ENTRY_VAL (old
, NPF_NTPWD
) ||
1162 strcmp (ENTRY_VAL (old
, NPF_NTPWD
), smb_nt_passwd
)) {
1163 need_to_modify
= True
;
1164 set_single_attribute (obj
, NPF_NTPWD
, smb_nt_passwd
,
1165 strlen (smb_nt_passwd
),
1166 EN_CRYPT
| EN_MODIFIED
);
1170 if (pdb_get_logon_time (sampass
) &&
1171 (!ENTRY_VAL (old
, NPF_LOGON_T
) ||
1172 strcmp (ENTRY_VAL (old
, NPF_LOGON_T
), logon_t
))) {
1173 need_to_modify
= True
;
1174 set_single_attribute (obj
, NPF_LOGON_T
, logon_t
,
1175 strlen (logon_t
), EN_MODIFIED
);
1179 if (pdb_get_logoff_time (sampass
) &&
1180 (!ENTRY_VAL (old
, NPF_LOGOFF_T
) ||
1181 strcmp (ENTRY_VAL (old
, NPF_LOGOFF_T
), logoff_t
))) {
1182 need_to_modify
= True
;
1183 set_single_attribute (obj
, NPF_LOGOFF_T
, logoff_t
,
1184 strlen (logoff_t
), EN_MODIFIED
);
1188 if (pdb_get_kickoff_time (sampass
) &&
1189 (!ENTRY_VAL (old
, NPF_KICK_T
) ||
1190 strcmp (ENTRY_VAL (old
, NPF_KICK_T
), kickoff_t
))) {
1191 need_to_modify
= True
;
1192 set_single_attribute (obj
, NPF_KICK_T
, kickoff_t
,
1198 if (pdb_get_pass_last_set_time (sampass
) &&
1199 (!ENTRY_VAL (old
, NPF_PWDLSET_T
) ||
1200 strcmp (ENTRY_VAL (old
, NPF_PWDLSET_T
), pwdlset_t
))) {
1201 need_to_modify
= True
;
1202 set_single_attribute (obj
, NPF_PWDLSET_T
, pwdlset_t
,
1208 if (pdb_get_pass_can_change_time (sampass
) &&
1209 (!ENTRY_VAL (old
, NPF_PWDCCHG_T
) ||
1210 strcmp (ENTRY_VAL (old
, NPF_PWDCCHG_T
), pwdlchg_t
))) {
1211 need_to_modify
= True
;
1212 set_single_attribute (obj
, NPF_PWDCCHG_T
, pwdlchg_t
,
1218 if (pdb_get_pass_must_change_time (sampass
) &&
1219 (!ENTRY_VAL (old
, NPF_PWDMCHG_T
) ||
1220 strcmp (ENTRY_VAL (old
, NPF_PWDMCHG_T
), pwdmchg_t
))) {
1221 need_to_modify
= True
;
1222 set_single_attribute (obj
, NPF_PWDMCHG_T
, pwdmchg_t
,
1228 /* must support set, unset and change */
1229 if ((pdb_get_fullname (sampass
) &&
1230 !ENTRY_VAL (old
, NPF_FULL_NAME
)) ||
1231 (ENTRY_VAL (old
, NPF_FULL_NAME
) &&
1232 !pdb_get_fullname (sampass
)) ||
1233 (ENTRY_VAL (old
, NPF_FULL_NAME
) &&
1234 pdb_get_fullname (sampass
) &&
1235 strcmp (ENTRY_VAL (old
, NPF_FULL_NAME
), full_name
))) {
1236 need_to_modify
= True
;
1237 set_single_attribute (obj
, NPF_FULL_NAME
, full_name
,
1243 /* must support set, unset and change */
1244 if ((pdb_get_homedir (sampass
) &&
1245 !ENTRY_VAL (old
, NPF_HOME_DIR
)) ||
1246 (ENTRY_VAL (old
, NPF_HOME_DIR
) &&
1247 !pdb_get_homedir (sampass
)) ||
1248 (ENTRY_VAL (old
, NPF_HOME_DIR
) &&
1249 pdb_get_homedir (sampass
) &&
1250 strcmp (ENTRY_VAL (old
, NPF_HOME_DIR
),
1251 pdb_get_homedir (sampass
)))) {
1252 need_to_modify
= True
;
1253 set_single_attribute (obj
, NPF_HOME_DIR
,
1254 pdb_get_homedir (sampass
),
1255 strlen (pdb_get_homedir
1261 /* must support set, unset and change */
1262 if ((pdb_get_dir_drive (sampass
) &&
1263 !ENTRY_VAL (old
, NPF_DIR_DRIVE
)) ||
1264 (ENTRY_VAL (old
, NPF_DIR_DRIVE
) &&
1265 !pdb_get_dir_drive (sampass
)) ||
1266 (ENTRY_VAL (old
, NPF_DIR_DRIVE
) &&
1267 pdb_get_dir_drive (sampass
) &&
1268 strcmp (ENTRY_VAL (old
, NPF_DIR_DRIVE
),
1269 pdb_get_dir_drive (sampass
)))) {
1270 need_to_modify
= True
;
1271 set_single_attribute (obj
, NPF_DIR_DRIVE
,
1272 pdb_get_dir_drive (sampass
),
1273 strlen (pdb_get_dir_drive
1279 /* must support set, unset and change */
1280 if (((pdb_get_logon_script (sampass
) &&
1281 !ENTRY_VAL (old
, NPF_LOGON_SCRIPT
)) ||
1282 ((ENTRY_VAL (old
, NPF_LOGON_SCRIPT
) &&
1283 (!pdb_get_logon_script (sampass
)))) ||
1284 ((ENTRY_VAL (old
, NPF_LOGON_SCRIPT
) &&
1285 pdb_get_logon_script (sampass
) &&
1286 strcmp (ENTRY_VAL (old
, NPF_LOGON_SCRIPT
),
1287 pdb_get_logon_script (sampass
)))))) {
1288 need_to_modify
= True
;
1289 set_single_attribute (obj
, NPF_LOGON_SCRIPT
,
1290 pdb_get_logon_script (sampass
),
1291 strlen (pdb_get_logon_script
1297 /* must support set, unset and change */
1298 if ((pdb_get_profile_path (sampass
) &&
1299 !ENTRY_VAL (old
, NPF_PROFILE_PATH
)) ||
1300 (ENTRY_VAL (old
, NPF_PROFILE_PATH
) &&
1301 !pdb_get_profile_path (sampass
)) ||
1302 (ENTRY_VAL (old
, NPF_PROFILE_PATH
) &&
1303 pdb_get_profile_path (sampass
) &&
1304 strcmp (ENTRY_VAL (old
, NPF_PROFILE_PATH
),
1305 pdb_get_profile_path (sampass
)))) {
1306 need_to_modify
= True
;
1307 set_single_attribute (obj
, NPF_PROFILE_PATH
,
1308 pdb_get_profile_path (sampass
),
1309 strlen (pdb_get_profile_path
1315 /* must support set, unset and change */
1316 if ((pdb_get_acct_desc (sampass
) &&
1317 !ENTRY_VAL (old
, NPF_ACCT_DESC
)) ||
1318 (ENTRY_VAL (old
, NPF_ACCT_DESC
) &&
1319 !pdb_get_acct_desc (sampass
)) ||
1320 (ENTRY_VAL (old
, NPF_ACCT_DESC
) &&
1321 pdb_get_acct_desc (sampass
) &&
1322 strcmp (ENTRY_VAL (old
, NPF_ACCT_DESC
), acct_desc
))) {
1323 need_to_modify
= True
;
1324 set_single_attribute (obj
, NPF_ACCT_DESC
, acct_desc
,
1330 /* must support set, unset and change */
1331 if ((pdb_get_workstations (sampass
) &&
1332 !ENTRY_VAL (old
, NPF_WORKSTATIONS
)) ||
1333 (ENTRY_VAL (old
, NPF_WORKSTATIONS
) &&
1334 !pdb_get_workstations (sampass
)) ||
1335 (ENTRY_VAL (old
, NPF_WORKSTATIONS
) &&
1336 (pdb_get_workstations (sampass
)) &&
1337 strcmp (ENTRY_VAL (old
, NPF_WORKSTATIONS
),
1338 pdb_get_workstations (sampass
)))) {
1339 need_to_modify
= True
;
1340 set_single_attribute (obj
, NPF_WORKSTATIONS
,
1341 pdb_get_workstations (sampass
),
1342 strlen (pdb_get_workstations
1348 if ((pdb_get_hours_len (sampass
) !=
1349 ENTRY_LEN (old
, NPF_HOURS
))
1350 || memcmp (pdb_get_hours (sampass
),
1351 ENTRY_VAL (old
, NPF_HOURS
), ENTRY_LEN (old
,
1354 need_to_modify
= True
;
1355 /* set_single_attribute will add 1 for len ... */
1356 set_single_attribute (obj
, NPF_HOURS
,
1357 pdb_get_hours (sampass
),
1358 pdb_get_hours_len (sampass
) - 1,
1362 const char *homedir
, *dirdrive
, *logon_script
, *profile_path
,
1365 *empty
= '\0'; /* empty string */
1367 set_single_attribute (obj
, NPF_NAME
, name
, strlen (name
), 0);
1368 set_single_attribute (obj
, NPF_UID
, uid
, strlen (uid
), 0);
1369 set_single_attribute (obj
, NPF_USER_RID
, user_rid
,
1370 strlen (user_rid
), 0);
1371 set_single_attribute (obj
, NPF_SMB_GRPID
, gid
, strlen (gid
),
1373 set_single_attribute (obj
, NPF_GROUP_RID
, group_rid
,
1374 strlen (group_rid
), 0);
1375 set_single_attribute (obj
, NPF_ACB
, acb
, strlen (acb
), 0);
1376 set_single_attribute (obj
, NPF_LMPWD
, smb_passwd
,
1377 strlen (smb_passwd
), EN_CRYPT
);
1378 set_single_attribute (obj
, NPF_NTPWD
, smb_nt_passwd
,
1379 strlen (smb_nt_passwd
), EN_CRYPT
);
1380 set_single_attribute (obj
, NPF_LOGON_T
, logon_t
,
1381 strlen (logon_t
), 0);
1382 set_single_attribute (obj
, NPF_LOGOFF_T
, logoff_t
,
1383 strlen (logoff_t
), 0);
1384 set_single_attribute (obj
, NPF_KICK_T
, kickoff_t
,
1385 strlen (kickoff_t
), 0);
1386 set_single_attribute (obj
, NPF_PWDLSET_T
, pwdlset_t
,
1387 strlen (pwdlset_t
), 0);
1388 set_single_attribute (obj
, NPF_PWDCCHG_T
, pwdlchg_t
,
1389 strlen (pwdlchg_t
), 0);
1390 set_single_attribute (obj
, NPF_PWDMCHG_T
, pwdmchg_t
,
1391 strlen (pwdmchg_t
), 0);
1392 set_single_attribute (obj
, NPF_FULL_NAME
,
1393 full_name
, strlen (full_name
), 0);
1395 if (!(homedir
= pdb_get_homedir (sampass
)))
1398 set_single_attribute (obj
, NPF_HOME_DIR
,
1399 homedir
, strlen (homedir
), 0);
1401 if (!(dirdrive
= pdb_get_dir_drive (sampass
)))
1404 set_single_attribute (obj
, NPF_DIR_DRIVE
,
1405 dirdrive
, strlen (dirdrive
), 0);
1407 if (!(logon_script
= pdb_get_logon_script (sampass
)))
1408 logon_script
= empty
;
1410 set_single_attribute (obj
, NPF_LOGON_SCRIPT
,
1411 logon_script
, strlen (logon_script
), 0);
1413 if (!(profile_path
= pdb_get_profile_path (sampass
)))
1414 profile_path
= empty
;
1416 set_single_attribute (obj
, NPF_PROFILE_PATH
,
1417 profile_path
, strlen (profile_path
), 0);
1419 set_single_attribute (obj
, NPF_ACCT_DESC
,
1420 acct_desc
, strlen (acct_desc
), 0);
1422 if (!(workstations
= pdb_get_workstations (sampass
)))
1423 workstations
= empty
;
1425 set_single_attribute (obj
, NPF_WORKSTATIONS
,
1426 workstations
, strlen (workstations
), 0);
1428 /* set_single_attribute will add 1 for len ... */
1429 set_single_attribute (obj
, NPF_HOURS
,
1430 pdb_get_hours (sampass
),
1431 pdb_get_hours_len (sampass
) - 1, 0);
1434 return need_to_modify
;
1437 /***************************************************************
1438 calls nis_list, returns results.
1439 ****************************************************************/
1440 static nis_result
*nisp_get_nis_list (const char *nisname
, unsigned int flags
)
1446 flags
= FOLLOW_LINKS
| FOLLOW_PATH
| EXPAND_NAME
|
1449 for (i
= 0; i
< 2; i
++) {
1450 alarm (60); /* hopefully ok for long searches */
1451 result
= nis_list (nisname
, flags
, NULL
, NULL
);
1454 CatchSignal (SIGALRM
, SIGNAL_CAST SIG_DFL
);
1456 if (!(flags
& MASTER_ONLY
) && NIS_RES_NUMOBJ (result
) <= 0) {
1457 /* nis replicas are not in sync perhaps?
1458 * this can happen, if account was just added.
1460 DEBUG (10, ("will try master only\n"));
1461 nis_freeresult (result
);
1462 flags
|= MASTER_ONLY
;
1469 static void free_private_data(void **vp
)
1471 struct nisplus_private_info
**private = (struct nisplus_private_info
**)vp
;
1473 if ((*private)->result
) {
1474 nis_freeresult ((*private)->result
);
1479 /* No need to free any further, as it is talloc()ed */
1482 NTSTATUS
pdb_init_nisplussam (PDB_CONTEXT
* pdb_context
,
1483 PDB_METHODS
** pdb_method
, const char *location
)
1486 struct nisplus_private_info
*private = malloc (sizeof (struct nisplus_private_info
));
1488 ZERO_STRUCT(private);
1489 p
->location
= talloc_strdup(pdb_context
->mem_ctx
, location
);
1491 if (!NT_STATUS_IS_OK
1493 make_pdb_methods (pdb_context
->mem_ctx
, pdb_method
))) {
1497 (*pdb_method
)->name
= "nisplussam";
1499 /* Functions your pdb module doesn't provide should be set
1502 (*pdb_method
)->setsampwent
= nisplussam_setsampwent
;
1503 (*pdb_method
)->endsampwent
= nisplussam_endsampwent
;
1504 (*pdb_method
)->getsampwent
= nisplussam_getsampwent
;
1505 (*pdb_method
)->getsampwnam
= nisplussam_getsampwnam
;
1506 (*pdb_method
)->getsampwsid
= nisplussam_getsampwsid
;
1507 (*pdb_method
)->add_sam_account
= nisplussam_add_sam_account
;
1508 (*pdb_method
)->update_sam_account
= nisplussam_update_sam_account
;
1509 (*pdb_method
)->delete_sam_account
= nisplussam_delete_sam_account
;
1510 (*pdb_method
)->free_private_data
= free_private_data
;
1511 (*pdb_method
)->private_data
= private;
1513 return NT_STATUS_OK
;
1516 NTSTATUS
pdb_nisplus_init(void)
1518 return smb_register_passdb(PASSDB_INTERFACE_VERSION
, "nisplussam", pdb_init_nisplussam
);