trying to fix some linking issues with Solaris LDAP libraries.
[Samba.git] / source / passdb / pdb_nisplus.c
blob21be4b88fbadf9e3803115351fd2657e8ab773ae
1 /*
2 * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
3 * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
4 * Copyright (C) Benny Holmgren 1998 <bigfoot@astrakan.hgs.se>
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998.
6 * Copyright (C) Toomas Soome <tsoome@ut.ee> 2001
7 *
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
18 * You should have received a copy of the GNU General Public License along with
19 * this program; if not, write to the Free Software Foundation, Inc., 675
20 * Mass Ave, Cambridge, MA 02139, USA.
23 #include "includes.h"
25 #ifdef WITH_NISPLUS_SAM
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.
37 #if defined(GROUP)
38 #undef GROUP
39 #endif
41 #if defined(GROUP_OBJ)
42 #undef GROUP_OBJ
43 #endif
45 #endif
47 #include <rpcsvc/nis.h>
49 extern int DEBUGLEVEL;
50 extern pstring samlogon_user;
51 extern BOOL sam_logon_in_ssb;
53 struct nisp_enum_info
55 nis_result *result;
56 int enum_entry;
59 static struct nisp_enum_info global_nisp_ent;
60 static VOLATILE sig_atomic_t gotalarm;
62 /***************************************************************
64 the fields for the NIS+ table, generated from mknissmbpwtbl.sh, are:
66 name=S,nogw=r
67 uid=S,nogw=r
68 user_rid=S,nogw=r
69 smb_grpid=,nw+r
70 group_rid=,nw+r
71 acb=,nw+r
73 lmpwd=C,nw=,g=r,o=rm
74 ntpwd=C,nw=,g=r,o=rm
76 logon_t=,nw+r
77 logoff_t=,nw+r
78 kick_t=,nw+r
79 pwdlset_t=,nw+r
80 pwdlchg_t=,nw+r
81 pwdmchg_t=,nw+r
83 full_name=,nw+r
84 home_dir=,nw+r
85 dir_drive=,nw+r
86 logon_script=,nw+r
87 profile_path=,nw+r
88 acct_desc=,nw+r
89 workstations=,nw+r
91 hours=,nw+r
93 ****************************************************************/
95 #define NPF_NAME 0
96 #define NPF_UID 1
97 #define NPF_USER_RID 2
98 #define NPF_SMB_GRPID 3
99 #define NPF_GROUP_RID 4
100 #define NPF_ACB 5
101 #define NPF_LMPWD 6
102 #define NPF_NTPWD 7
103 #define NPF_LOGON_T 8
104 #define NPF_LOGOFF_T 9
105 #define NPF_KICK_T 10
106 #define NPF_PWDLSET_T 11
107 #define NPF_PWDCCHG_T 12
108 #define NPF_PWDMCHG_T 13
109 #define NPF_FULL_NAME 14
110 #define NPF_HOME_DIR 15
111 #define NPF_DIR_DRIVE 16
112 #define NPF_LOGON_SCRIPT 17
113 #define NPF_PROFILE_PATH 18
114 #define NPF_ACCT_DESC 19
115 #define NPF_WORKSTATIONS 20
116 #define NPF_HOURS 21
118 /***************************************************************
119 Signal function to tell us we timed out.
120 ****************************************************************/
121 static void gotalarm_sig(void)
123 gotalarm = 1;
126 /***************************************************************
127 make_nisname_from_user_rid
128 ****************************************************************/
129 static char *make_nisname_from_user_rid(uint32 rid, char *pfile)
131 static pstring nisname;
133 slprintf(nisname, sizeof(nisname)-1, "[user_rid=%d]%s", rid, pfile);
135 return nisname;
138 /***************************************************************
139 make_nisname_from_uid
140 ****************************************************************/
141 static char *make_nisname_from_uid(int uid, char *pfile)
143 static pstring nisname;
145 slprintf(nisname, sizeof(nisname)-1, "[uid=%d]%s", uid, pfile);
147 return nisname;
150 /***************************************************************
151 make_nisname_from_name
152 ****************************************************************/
153 static char *make_nisname_from_name(char *user_name, char *pfile)
155 static pstring nisname;
157 slprintf(nisname, sizeof(nisname)-1, "[name=%s]%s", user_name, pfile);
159 return nisname;
162 /***************************************************************
163 smb_passwd_table
165 * if only plain table in is in pfile, org_dir will be concated.
166 * so, at first we will clear path prefix from pfile, and
167 * then we will use pfiletmp as playground to put together full
168 * nisname string.
169 * such approach will make it possible to specify samba private dir
170 * AND still use NIS+ table. as all domain related data is normally
171 * stored in org_dir.DOMAIN, this should be ok to do.
172 ****************************************************************/
173 static char *smb_passwd_table(){
174 char *sp, *p = lp_smb_passwd_file();
175 #if 1
176 static pstring pfiletmp;
177 #endif
179 /* if lp_smb_passwd_file() returns anything wierd, pass it on */
180 if (!p || !*p) return p;
181 sp = strrchr( p, '/' );
182 if (sp) p=sp+1;
184 #if 1
185 /* append org_dir ONLY if plain table name is used.
186 why we do append it is because NIS_PATH env may not be set,
187 should we check if it's set?
188 do not append if lp_smb_passwd_file() returns an empty string
190 if (!strchr(p, '.')){
191 slprintf(pfiletmp, sizeof(pfiletmp)-1, "%s.org_dir", p);
192 return pfiletmp;
194 #endif
195 return p;
199 /*************************************************************************
200 gets a NIS+ attribute
201 *************************************************************************/
202 static void get_single_attribute(nis_object *new_obj, int col,
203 char *val, int len)
205 int entry_len;
207 if (new_obj == NULL || val == NULL) return;
209 entry_len = ENTRY_LEN(new_obj, col);
210 if (len > entry_len)
212 len = entry_len;
215 safe_strcpy(val, ENTRY_VAL(new_obj, col), len-1);
218 /************************************************************************
219 makes a struct sam_passwd from a NIS+ object.
220 ************************************************************************/
221 static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, nis_object *obj)
223 char *ptr;
224 pstring full_name; /* this must be translated to dos code page */
225 pstring acct_desc; /* this must be translated to dos code page */
226 pstring home_dir; /* set default value from smb.conf for user */
227 pstring home_drive; /* set default value from smb.conf for user */
228 pstring logon_script; /* set default value from smb.conf for user */
229 pstring profile_path; /* set default value from smb.conf for user */
230 pstring hours;
231 int hours_len;
232 unsigned char smbpwd[16];
233 unsigned char smbntpwd[16];
237 * time values. note: this code assumes 32bit time_t!
240 pdb_set_logon_time(pw_buf, (time_t)0);
241 ptr = ENTRY_VAL(obj, NPF_LOGON_T);
242 if(ptr && *ptr && (StrnCaseCmp(ptr, "LNT-", 4)==0)) {
243 int i;
244 ptr += 4;
245 for(i = 0; i < 8; i++) {
246 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
247 break;
249 if(i == 8) {
250 pdb_set_logon_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
254 pdb_set_logoff_time(pw_buf, get_time_t_max());
255 ptr = ENTRY_VAL(obj, NPF_LOGOFF_T);
256 if(ptr && *ptr && (StrnCaseCmp(ptr, "LOT-", 4)==0)) {
257 int i;
258 ptr += 4;
259 for(i = 0; i < 8; i++) {
260 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
261 break;
263 if(i == 8) {
264 pdb_set_logoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
268 pdb_set_kickoff_time(pw_buf, get_time_t_max());
269 ptr = ENTRY_VAL(obj, NPF_KICK_T);
270 if(ptr && *ptr && (StrnCaseCmp(ptr, "KOT-", 4)==0)) {
271 int i;
272 ptr += 4;
273 for(i = 0; i < 8; i++) {
274 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
275 break;
277 if(i == 8) {
278 pdb_set_kickoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
282 pdb_set_pass_last_set_time(pw_buf, (time_t)0);
283 ptr = ENTRY_VAL(obj, NPF_PWDLSET_T);
284 if(ptr && *ptr && (StrnCaseCmp(ptr, "LCT-", 4)==0)) {
285 int i;
286 ptr += 4;
287 for(i = 0; i < 8; i++) {
288 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
289 break;
291 if(i == 8) {
292 pdb_set_pass_last_set_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
296 pdb_set_pass_can_change_time(pw_buf, (time_t)0);
297 ptr = ENTRY_VAL(obj, NPF_PWDCCHG_T);
298 if(ptr && *ptr && (StrnCaseCmp(ptr, "CCT-", 4)==0)) {
299 int i;
300 ptr += 4;
301 for(i = 0; i < 8; i++) {
302 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
303 break;
305 if(i == 8) {
306 pdb_set_pass_can_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
310 pdb_set_pass_must_change_time(pw_buf, get_time_t_max()); /* Password never expires. */
311 ptr = ENTRY_VAL(obj, NPF_PWDMCHG_T);
312 if(ptr && *ptr && (StrnCaseCmp(ptr, "MCT-", 4)==0)) {
313 int i;
314 ptr += 4;
315 for(i = 0; i < 8; i++) {
316 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
317 break;
319 if(i == 8) {
320 pdb_set_pass_must_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
324 /* string values */
325 pdb_set_username(pw_buf, ENTRY_VAL(obj, NPF_NAME));
326 pdb_set_domain(pw_buf, lp_workgroup());
327 /* pdb_set_nt_username() -- cant set it here... */
329 get_single_attribute(obj, NPF_FULL_NAME, full_name, sizeof(pstring));
330 unix_to_dos(full_name);
331 pdb_set_fullname(pw_buf, full_name);
333 pdb_set_acct_ctrl(pw_buf, pdb_decode_acct_ctrl(ENTRY_VAL(obj,
334 NPF_ACB)));
336 get_single_attribute(obj, NPF_ACCT_DESC, acct_desc, sizeof(pstring));
337 unix_to_dos(acct_desc);
338 pdb_set_acct_desc(pw_buf, acct_desc);
340 pdb_set_workstations(pw_buf, ENTRY_VAL(obj, NPF_WORKSTATIONS));
341 pdb_set_munged_dial(pw_buf, NULL);
343 /* Might want to consult sys_getpwnam for the following two.
344 for now, use same default as pdb_fill-default_sam */
346 ptr = ENTRY_VAL(obj, NPF_UID);
347 pdb_set_uid(pw_buf, ptr ? atoi(ptr) : -1);
349 ptr = ENTRY_VAL(obj, NPF_SMB_GRPID);
350 pdb_set_gid(pw_buf, ptr ? atoi(ptr) : -1);
353 ptr = ENTRY_VAL(obj, NPF_USER_RID);
354 pdb_set_user_rid(pw_buf, ptr ? atoi(ptr) :
355 pdb_uid_to_user_rid(pdb_get_uid(pw_buf)));
357 ptr = ENTRY_VAL(obj, NPF_GROUP_RID);
358 pdb_set_group_rid(pw_buf, ptr ? atoi(ptr) :
359 pdb_gid_to_group_rid(pdb_get_gid(pw_buf)));
362 /* values, must exist for user */
363 if( !(pdb_get_acct_ctrl(pw_buf) & ACB_WSTRUST) ) {
364 /* FIXME!! This doesn't belong here.
365 Should be set in net_sam_logon()
366 --jerry */
367 pstrcpy(samlogon_user, pdb_get_username(pw_buf));
369 get_single_attribute(obj, NPF_HOME_DIR, home_dir, sizeof(pstring));
370 if( !(home_dir && *home_dir) ) {
371 pstrcpy(home_dir, lp_logon_home());
372 pdb_set_homedir(pw_buf, home_dir, False);
374 else
375 pdb_set_homedir(pw_buf, home_dir, True);
377 get_single_attribute(obj, NPF_DIR_DRIVE, home_drive, sizeof(pstring));
378 if( !(home_drive && *home_drive) ) {
379 pstrcpy(home_drive, lp_logon_drive());
380 pdb_set_dir_drive(pw_buf, home_drive, False);
382 else
383 pdb_set_dir_drive(pw_buf, home_drive, True);
385 get_single_attribute(obj, NPF_LOGON_SCRIPT, logon_script,
386 sizeof(pstring));
387 if( !(logon_script && *logon_script) ) {
388 pstrcpy(logon_script, lp_logon_script());
389 pdb_set_logon_script(pw_buf, logon_script, False);
391 else
392 pdb_set_logon_script(pw_buf, logon_script, True);
394 get_single_attribute(obj, NPF_PROFILE_PATH, profile_path, sizeof(pstring));
395 if( !(profile_path && *profile_path) ) {
396 pstrcpy(profile_path, lp_logon_path());
397 pdb_set_profile_path(pw_buf, profile_path, False);
399 else
400 pdb_set_profile_path(pw_buf, profile_path, True);
403 else
405 /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
406 pdb_set_group_rid (pw_buf, DOMAIN_GROUP_RID_USERS);
409 /* Check the lanman password column. */
410 ptr = ENTRY_VAL(obj, NPF_LMPWD);
411 if (!pdb_set_lanman_passwd(pw_buf, NULL))
412 return False;
414 if (!strncasecmp(ptr, "NO PASSWORD", 11)) {
415 pdb_set_acct_ctrl(pw_buf, pdb_get_acct_ctrl(pw_buf) | ACB_PWNOTREQ);
416 } else {
417 if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbpwd)) {
418 DEBUG(0, ("malformed LM pwd entry: %s.\n",
419 pdb_get_username(pw_buf)));
420 return False;
422 if (!pdb_set_lanman_passwd(pw_buf, smbpwd))
423 return False;
426 /* Check the NT password column. */
427 ptr = ENTRY_VAL(obj, NPF_NTPWD);
428 if (!pdb_set_nt_passwd(pw_buf, NULL))
429 return False;
431 if (!(pdb_get_acct_ctrl(pw_buf) & ACB_PWNOTREQ) &&
432 strncasecmp(ptr, "NO PASSWORD", 11)) {
433 if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbntpwd)) {
434 DEBUG(0, ("malformed NT pwd entry:\
435 uid = %d.\n",
436 pdb_get_uid(pw_buf)));
437 return False;
439 if (!pdb_set_nt_passwd(pw_buf, smbntpwd))
440 return False;
443 pdb_set_unknown_3(pw_buf, 0xffffff); /* don't know */
444 pdb_set_logon_divs(pw_buf, 168); /* hours per week */
446 if( (hours_len = ENTRY_LEN(obj, NPF_HOURS)) == 21 ) {
447 memcpy(hours, ENTRY_VAL(obj, NPF_HOURS), hours_len);
448 } else {
449 hours_len = 21; /* 21 times 8 bits = 168 */
450 /* available at all hours */
451 memset(hours, 0xff, hours_len);
453 pdb_set_hours_len(pw_buf, hours_len);
454 pdb_set_hours(pw_buf, (uchar *)hours);
456 pdb_set_unknown_5(pw_buf, 0x00020000); /* don't know */
457 pdb_set_unknown_6(pw_buf, 0x000004ec); /* don't know */
459 return True;
462 /************************************************************************
463 makes a struct sam_passwd from a NIS+ result.
464 ************************************************************************/
465 static BOOL make_sam_from_nisresult(SAM_ACCOUNT *pw_buf, nis_result *result)
467 if (pw_buf == NULL || result == NULL) return False;
469 if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND)
471 DEBUG(0, ("NIS+ lookup failure: %s\n",
472 nis_sperrno(result->status)));
473 return False;
476 /* User not found. */
477 if (NIS_RES_NUMOBJ(result) <= 0)
479 DEBUG(10, ("user not found in NIS+\n"));
480 return False;
483 if (NIS_RES_NUMOBJ(result) > 1)
485 DEBUG(10, ("WARNING: Multiple entries for user in NIS+ table!\n"));
488 /* Grab the first hit. */
489 return make_sam_from_nisp_object(pw_buf, &NIS_RES_OBJECT(result)[0]);
492 /*************************************************************************
493 sets a NIS+ attribute
494 *************************************************************************/
495 static void set_single_attribute(nis_object *new_obj, int col,
496 char *val, int len, int flags)
498 if (new_obj == NULL) return;
500 ENTRY_VAL(new_obj, col) = val;
501 ENTRY_LEN(new_obj, col) = len+1;
503 if (flags != 0)
505 new_obj->EN_data.en_cols.en_cols_val[col].ec_flags = flags;
509 /***************************************************************
510 copy or modify nis object. this object is used to add or update
511 nisplus table entry.
512 ****************************************************************/
513 static BOOL init_nisp_from_sam(nis_object *obj, SAM_ACCOUNT *sampass,
514 nis_object *old)
517 * Fill nis_object for entry add or update.
518 * if we are updateing, we have to find out differences and set
519 * EN_MODIFIED flag. also set need_to_modify to trigger
520 * nis_modify_entry() call in pdb_update_sam_account().
522 * TODO:
523 * get data from SAM
524 * if (modify) get data from nis_object, compare and store if
525 * different + set EN_MODIFIED and need_to_modify
526 * else
527 * store
529 BOOL need_to_modify = False;
530 char *name; /* from SAM */
531 /* these must be static or allocate and free entry columns! */
532 static fstring uid; /* from SAM */
533 static fstring user_rid; /* from SAM */
534 static fstring gid; /* from SAM */
535 static fstring group_rid; /* from SAM */
536 char *acb; /* from SAM */
537 static fstring smb_passwd; /* from SAM */
538 static fstring smb_nt_passwd; /* from SAM */
539 static fstring logon_t; /* from SAM */
540 static fstring logoff_t; /* from SAM */
541 static fstring kickoff_t; /* from SAM */
542 static fstring pwdlset_t; /* from SAM */
543 static fstring pwdlchg_t; /* from SAM */
544 static fstring pwdmchg_t; /* from SAM */
545 static fstring full_name; /* from SAM */
546 static fstring acct_desc; /* from SAM */
547 static char empty[1]; /* just an empty string */
550 name = pdb_get_username(sampass);
551 slprintf(uid, sizeof(uid)-1, "%u", pdb_get_uid(sampass));
552 slprintf(user_rid, sizeof(user_rid)-1, "%u",
553 pdb_get_user_rid(sampass)? pdb_get_user_rid(sampass):
554 pdb_uid_to_user_rid(pdb_get_uid(sampass)));
555 slprintf(gid, sizeof(gid)-1, "%u", pdb_get_gid(sampass));
556 slprintf(group_rid, sizeof(group_rid)-1, "%u",
557 pdb_get_group_rid(sampass)? pdb_get_group_rid(sampass):
558 pdb_gid_to_group_rid(pdb_get_gid(sampass)));
559 acb = pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sampass),
560 NEW_PW_FORMAT_SPACE_PADDED_LEN);
561 pdb_sethexpwd (smb_passwd, pdb_get_lanman_passwd(sampass),
562 pdb_get_acct_ctrl(sampass));
563 pdb_sethexpwd (smb_nt_passwd, pdb_get_nt_passwd(sampass),
564 pdb_get_acct_ctrl(sampass));
565 slprintf(logon_t, 13, "LNT-%08X",
566 (uint32)pdb_get_logon_time(sampass));
567 slprintf(logoff_t, 13, "LOT-%08X",
568 (uint32)pdb_get_logoff_time(sampass));
569 slprintf(kickoff_t, 13, "KOT-%08X",
570 (uint32)pdb_get_kickoff_time(sampass));
571 slprintf(pwdlset_t, 13, "LCT-%08X",
572 (uint32)pdb_get_pass_last_set_time(sampass));
573 slprintf(pwdlchg_t, 13, "CCT-%08X",
574 (uint32)pdb_get_pass_can_change_time(sampass));
575 slprintf(pwdmchg_t, 13, "MCT-%08X",
576 (uint32)pdb_get_pass_must_change_time(sampass));
577 safe_strcpy(full_name, pdb_get_fullname(sampass), sizeof(full_name)-1);
578 dos_to_unix(full_name);
579 safe_strcpy(acct_desc, pdb_get_acct_desc(sampass), sizeof(acct_desc)-1);
580 dos_to_unix(acct_desc);
582 if( old ) {
583 /* name */
584 if(strcmp(ENTRY_VAL(old, NPF_NAME), name))
586 need_to_modify = True;
587 set_single_attribute(obj, NPF_NAME, name, strlen(name),
588 EN_MODIFIED);
592 /* uid */
593 if(pdb_get_uid(sampass) != -1) {
594 if(!ENTRY_VAL(old, NPF_UID) || strcmp(ENTRY_VAL(old, NPF_UID), uid))
596 need_to_modify = True;
597 set_single_attribute(obj, NPF_UID, uid,
598 strlen(uid), EN_MODIFIED);
602 /* user_rid */
603 if (pdb_get_user_rid(sampass)) {
604 if(!ENTRY_VAL(old, NPF_USER_RID) ||
605 strcmp(ENTRY_VAL(old, NPF_USER_RID), user_rid) ) {
606 need_to_modify = True;
607 set_single_attribute(obj, NPF_USER_RID, user_rid,
608 strlen(user_rid), EN_MODIFIED);
612 /* smb_grpid */
613 if (pdb_get_gid(sampass) != -1) {
614 if(!ENTRY_VAL(old, NPF_SMB_GRPID) ||
615 strcmp(ENTRY_VAL(old, NPF_SMB_GRPID), gid) ) {
616 need_to_modify = True;
617 set_single_attribute(obj, NPF_SMB_GRPID, gid,
618 strlen(gid), EN_MODIFIED);
622 /* group_rid */
623 if (pdb_get_group_rid(sampass)) {
624 if(!ENTRY_VAL(old, NPF_GROUP_RID) ||
625 strcmp(ENTRY_VAL(old, NPF_GROUP_RID), group_rid) ) {
626 need_to_modify = True;
627 set_single_attribute(obj, NPF_GROUP_RID, group_rid,
628 strlen(group_rid), EN_MODIFIED);
632 /* acb */
633 if (!ENTRY_VAL(old, NPF_ACB) ||
634 strcmp(ENTRY_VAL(old, NPF_ACB), acb)) {
635 need_to_modify = True;
636 set_single_attribute(obj, NPF_ACB, acb, strlen(acb), EN_MODIFIED);
639 /* lmpwd */
640 if(!ENTRY_VAL(old, NPF_LMPWD) ||
641 strcmp(ENTRY_VAL(old, NPF_LMPWD), smb_passwd) ) {
642 need_to_modify = True;
643 set_single_attribute(obj, NPF_LMPWD, smb_passwd,
644 strlen(smb_passwd), EN_CRYPT|EN_MODIFIED);
647 /* ntpwd */
648 if(!ENTRY_VAL(old, NPF_NTPWD) ||
649 strcmp(ENTRY_VAL(old, NPF_NTPWD), smb_nt_passwd) ) {
650 need_to_modify = True;
651 set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd,
652 strlen(smb_nt_passwd), EN_CRYPT|EN_MODIFIED);
655 /* logon_t */
656 if( pdb_get_logon_time(sampass) &&
657 (!ENTRY_VAL(old, NPF_LOGON_T) ||
658 strcmp(ENTRY_VAL(old, NPF_LOGON_T), logon_t ))) {
659 need_to_modify = True;
660 set_single_attribute(obj, NPF_LOGON_T, logon_t,
661 strlen(logon_t), EN_MODIFIED);
664 /* logoff_t */
665 if( pdb_get_logoff_time(sampass) &&
666 (!ENTRY_VAL(old, NPF_LOGOFF_T) ||
667 strcmp(ENTRY_VAL(old, NPF_LOGOFF_T), logoff_t))) {
668 need_to_modify = True;
669 set_single_attribute(obj, NPF_LOGOFF_T, logoff_t,
670 strlen(logoff_t), EN_MODIFIED);
673 /* kick_t */
674 if( pdb_get_kickoff_time(sampass) &&
675 (!ENTRY_VAL(old, NPF_KICK_T) ||
676 strcmp(ENTRY_VAL(old, NPF_KICK_T), kickoff_t))) {
677 need_to_modify = True;
678 set_single_attribute(obj, NPF_KICK_T, kickoff_t,
679 strlen(kickoff_t), EN_MODIFIED);
682 /* pwdlset_t */
683 if( pdb_get_pass_last_set_time(sampass) &&
684 (!ENTRY_VAL(old, NPF_PWDLSET_T) ||
685 strcmp(ENTRY_VAL(old, NPF_PWDLSET_T), pwdlset_t))) {
686 need_to_modify = True;
687 set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t,
688 strlen(pwdlset_t), EN_MODIFIED);
691 /* pwdlchg_t */
692 if( pdb_get_pass_can_change_time(sampass) &&
693 (!ENTRY_VAL(old, NPF_PWDCCHG_T) ||
694 strcmp(ENTRY_VAL(old, NPF_PWDCCHG_T), pwdlchg_t))) {
695 need_to_modify = True;
696 set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t,
697 strlen(pwdlchg_t), EN_MODIFIED);
700 /* pwdmchg_t */
701 if( pdb_get_pass_must_change_time(sampass) &&
702 (!ENTRY_VAL(old, NPF_PWDMCHG_T) ||
703 strcmp(ENTRY_VAL(old, NPF_PWDMCHG_T), pwdmchg_t))) {
704 need_to_modify = True;
705 set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t,
706 strlen(pwdmchg_t), EN_MODIFIED);
709 /* full_name */
710 /* must support set, unset and change */
711 if ( (pdb_get_fullname(sampass) &&
712 !ENTRY_VAL(old, NPF_FULL_NAME)) ||
713 (ENTRY_VAL(old, NPF_FULL_NAME) &&
714 !pdb_get_fullname(sampass)) ||
715 (ENTRY_VAL(old, NPF_FULL_NAME) &&
716 pdb_get_fullname(sampass) &&
717 strcmp( ENTRY_VAL(old, NPF_FULL_NAME), full_name ))) {
718 need_to_modify = True;
719 set_single_attribute(obj, NPF_FULL_NAME, full_name,
720 strlen(full_name), EN_MODIFIED);
723 /* home_dir */
724 /* must support set, unset and change */
725 if( (pdb_get_homedir(sampass) &&
726 !ENTRY_VAL(old, NPF_HOME_DIR)) ||
727 (ENTRY_VAL(old, NPF_HOME_DIR) &&
728 !pdb_get_homedir(sampass)) ||
729 (ENTRY_VAL(old, NPF_HOME_DIR) &&
730 pdb_get_homedir(sampass) &&
731 strcmp( ENTRY_VAL(old, NPF_HOME_DIR),
732 pdb_get_homedir(sampass)))) {
733 need_to_modify = True;
734 set_single_attribute(obj, NPF_HOME_DIR, pdb_get_homedir(sampass),
735 strlen(pdb_get_homedir(sampass)), EN_MODIFIED);
738 /* dir_drive */
739 /* must support set, unset and change */
740 if( (pdb_get_dirdrive(sampass) &&
741 !ENTRY_VAL(old, NPF_DIR_DRIVE)) ||
742 (ENTRY_VAL(old, NPF_DIR_DRIVE) &&
743 !pdb_get_dirdrive(sampass)) ||
744 (ENTRY_VAL(old, NPF_DIR_DRIVE) &&
745 pdb_get_dirdrive(sampass) &&
746 strcmp( ENTRY_VAL(old, NPF_DIR_DRIVE),
747 pdb_get_dirdrive(sampass)))) {
748 need_to_modify = True;
749 set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dirdrive(sampass),
750 strlen(pdb_get_dirdrive(sampass)), EN_MODIFIED);
753 /* logon_script */
754 /* must support set, unset and change */
755 if( (pdb_get_logon_script(sampass) &&
756 !ENTRY_VAL(old, NPF_LOGON_SCRIPT) ||
757 (ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
758 !pdb_get_logon_script(sampass)) ||
759 ( ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
760 pdb_get_logon_script(sampass) &&
761 strcmp( ENTRY_VAL(old, NPF_LOGON_SCRIPT),
762 pdb_get_logon_script(sampass))))) {
763 need_to_modify = True;
764 set_single_attribute(obj, NPF_LOGON_SCRIPT,
765 pdb_get_logon_script(sampass),
766 strlen(pdb_get_logon_script(sampass)),
767 EN_MODIFIED);
770 /* profile_path */
771 /* must support set, unset and change */
772 if( (pdb_get_profile_path(sampass) &&
773 !ENTRY_VAL(old, NPF_PROFILE_PATH)) ||
774 (ENTRY_VAL(old, NPF_PROFILE_PATH) &&
775 !pdb_get_profile_path(sampass)) ||
776 (ENTRY_VAL(old, NPF_PROFILE_PATH) &&
777 pdb_get_profile_path(sampass) &&
778 strcmp( ENTRY_VAL(old, NPF_PROFILE_PATH),
779 pdb_get_profile_path(sampass) ) )) {
780 need_to_modify = True;
781 set_single_attribute(obj, NPF_PROFILE_PATH,
782 pdb_get_profile_path(sampass),
783 strlen(pdb_get_profile_path(sampass)),
784 EN_MODIFIED);
787 /* acct_desc */
788 /* must support set, unset and change */
789 if( (pdb_get_acct_desc(sampass) &&
790 !ENTRY_VAL(old, NPF_ACCT_DESC)) ||
791 (ENTRY_VAL(old, NPF_ACCT_DESC) &&
792 !pdb_get_acct_desc(sampass)) ||
793 (ENTRY_VAL(old, NPF_ACCT_DESC) &&
794 pdb_get_acct_desc(sampass) &&
795 strcmp( ENTRY_VAL(old, NPF_ACCT_DESC), acct_desc ) )) {
796 need_to_modify = True;
797 set_single_attribute(obj, NPF_ACCT_DESC, acct_desc,
798 strlen(acct_desc), EN_MODIFIED);
801 /* workstations */
802 /* must support set, unset and change */
803 if ( (pdb_get_workstations(sampass) &&
804 !ENTRY_VAL(old, NPF_WORKSTATIONS) ) ||
805 (ENTRY_VAL(old, NPF_WORKSTATIONS) &&
806 !pdb_get_workstations(sampass)) ||
807 (ENTRY_VAL(old, NPF_WORKSTATIONS) &&
808 pdb_get_workstations(sampass)) &&
809 strcmp( ENTRY_VAL(old, NPF_WORKSTATIONS),
810 pdb_get_workstations(sampass))) {
811 need_to_modify = True;
812 set_single_attribute(obj, NPF_WORKSTATIONS,
813 pdb_get_workstations(sampass),
814 strlen(pdb_get_workstations(sampass)),
815 EN_MODIFIED);
818 /* hours */
819 if ((pdb_get_hours_len(sampass) != ENTRY_LEN(old, NPF_HOURS)) ||
820 memcmp(pdb_get_hours(sampass), ENTRY_VAL(old, NPF_HOURS),
821 ENTRY_LEN(old, NPF_HOURS))) {
822 need_to_modify = True;
823 /* set_single_attribute will add 1 for len ... */
824 set_single_attribute(obj, NPF_HOURS, (char *)pdb_get_hours(sampass),
825 pdb_get_hours_len(sampass)-1, EN_MODIFIED);
827 } else {
828 char *homedir, *dirdrive, *logon_script, *profile_path, *workstations;
830 *empty = '\0'; /* empty string */
832 set_single_attribute(obj, NPF_NAME, name, strlen(name), 0);
833 set_single_attribute(obj, NPF_UID, uid, strlen(uid), 0);
834 set_single_attribute(obj, NPF_USER_RID, user_rid,
835 strlen(user_rid), 0);
836 set_single_attribute(obj, NPF_SMB_GRPID, gid, strlen(gid), 0);
837 set_single_attribute(obj, NPF_GROUP_RID, group_rid,
838 strlen(group_rid), 0);
839 set_single_attribute(obj, NPF_ACB, acb, strlen(acb), 0);
840 set_single_attribute(obj, NPF_LMPWD, smb_passwd,
841 strlen(smb_passwd), EN_CRYPT);
842 set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd,
843 strlen(smb_nt_passwd), EN_CRYPT);
844 set_single_attribute(obj, NPF_LOGON_T, logon_t,
845 strlen(logon_t), 0);
846 set_single_attribute(obj, NPF_LOGOFF_T, logoff_t,
847 strlen(logoff_t), 0);
848 set_single_attribute(obj, NPF_KICK_T, kickoff_t,
849 strlen(kickoff_t),0);
850 set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t,
851 strlen(pwdlset_t), 0);
852 set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t,
853 strlen(pwdlchg_t), 0);
854 set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t,
855 strlen(pwdmchg_t), 0);
856 set_single_attribute(obj, NPF_FULL_NAME ,
857 full_name, strlen(full_name), 0);
859 if(!(homedir = pdb_get_homedir(sampass)))
860 homedir = empty;
862 set_single_attribute(obj, NPF_HOME_DIR,
863 homedir, strlen(homedir), 0);
865 if(!(dirdrive = pdb_get_dirdrive(sampass)))
866 dirdrive = empty;
868 set_single_attribute(obj, NPF_DIR_DRIVE,
869 dirdrive, strlen(dirdrive), 0);
871 if(!(logon_script = pdb_get_logon_script(sampass)))
872 logon_script = empty;
874 set_single_attribute(obj, NPF_LOGON_SCRIPT,
875 logon_script, strlen(logon_script), 0);
877 if(!(profile_path = pdb_get_profile_path(sampass)))
878 profile_path = empty;
880 set_single_attribute(obj, NPF_PROFILE_PATH,
881 profile_path, strlen(profile_path), 0);
883 set_single_attribute(obj, NPF_ACCT_DESC,
884 acct_desc, strlen(acct_desc), 0);
886 if(!(workstations = pdb_get_workstations(sampass)))
887 workstations = empty;
889 set_single_attribute(obj, NPF_WORKSTATIONS,
890 workstations, strlen(workstations), 0);
892 /* set_single_attribute will add 1 for len ... */
893 set_single_attribute(obj, NPF_HOURS,
894 (char *)pdb_get_hours(sampass),
895 pdb_get_hours_len(sampass)-1, 0);
898 return need_to_modify;
901 /***************************************************************
902 calls nis_list, returns results.
903 ****************************************************************/
904 static nis_result *nisp_get_nis_list(char *nis_name, unsigned int flags)
906 nis_result *result;
907 int i;
909 if( ! flags)
910 flags = FOLLOW_LINKS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP;
912 for(i = 0; i<2;i++ ) {
913 alarm(60); /* hopefully ok for long searches */
914 result = nis_list(nis_name, flags,NULL,NULL);
916 alarm(0);
917 CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
919 if (gotalarm)
921 DEBUG(0,("NIS+ lookup time out\n"));
922 nis_freeresult(result);
923 return NULL;
925 if( !(flags & MASTER_ONLY) && NIS_RES_NUMOBJ(result) <= 0 ) {
926 /* nis replicas are not in sync perhaps?
927 * this can happen, if account was just added.
929 DEBUG(10,("will try master only\n"));
930 nis_freeresult(result);
931 flags |= MASTER_ONLY;
932 } else
933 break;
935 return result;
938 /***************************************************************
939 Start to enumerate the nisplus passwd list.
940 ****************************************************************/
941 BOOL pdb_setsampwent(BOOL update)
943 char *pfile = smb_passwd_table();
945 pdb_endsampwent(); /* just in case */
946 global_nisp_ent.result = nisp_get_nis_list( pfile, 0 );
947 global_nisp_ent.enum_entry = 0;
948 return global_nisp_ent.result != NULL ? True : False;
951 /***************************************************************
952 End enumeration of the nisplus passwd list.
953 ****************************************************************/
954 void pdb_endsampwent(void)
956 if( global_nisp_ent.result )
957 nis_freeresult(global_nisp_ent.result);
958 global_nisp_ent.result = NULL;
959 global_nisp_ent.enum_entry = 0;
962 /*************************************************************************
963 Routine to return the next entry in the nisplus passwd list.
964 *************************************************************************/
965 BOOL pdb_getsampwent(SAM_ACCOUNT *user)
967 int enum_entry = (int)(global_nisp_ent.enum_entry);
968 nis_result *result = global_nisp_ent.result;
970 if (user==NULL) {
971 DEBUG(0,("SAM_ACCOUNT is NULL.\n"));
972 return False;
975 if (result == NULL ||
976 enum_entry < 0 || enum_entry >= (NIS_RES_NUMOBJ(result) - 1))
978 return False;
981 if(!make_sam_from_nisp_object(user, &NIS_RES_OBJECT(result)[enum_entry]) )
983 DEBUG(0,("Bad SAM_ACCOUNT entry returned from NIS+!\n"));
984 return False;
986 (int)(global_nisp_ent.enum_entry)++;
987 return True;
990 /*************************************************************************
991 Routine to search the nisplus passwd file for an entry matching the username
992 *************************************************************************/
993 BOOL pdb_getsampwnam(SAM_ACCOUNT * user, char *sname)
995 /* Static buffers we will return. */
996 nis_result *result = NULL;
997 pstring nisname;
998 BOOL ret;
999 char *pfile = smb_passwd_table();
1000 int i;
1002 if (!*pfile)
1004 DEBUG(0, ("No SMB password file set\n"));
1005 return False;
1008 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", sname, pfile);
1009 DEBUG(10, ("search by nisname: %s\n", nisname));
1011 /* Search the table. */
1013 if(!(result = nisp_get_nis_list(nisname, 0)))
1015 return False;
1018 ret = make_sam_from_nisresult(user, result);
1019 nis_freeresult(result);
1021 return ret;
1024 /*************************************************************************
1025 Routine to search the nisplus passwd file for an entry matching the username
1026 *************************************************************************/
1027 BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
1029 nis_result *result;
1030 char *nisname;
1031 BOOL ret;
1032 char *pfile = smb_passwd_table();
1034 if (!*pfile)
1036 DEBUG(0, ("no SMB password file set\n"));
1037 return False;
1040 nisname = make_nisname_from_user_rid(rid, pfile);
1042 DEBUG(10, ("search by rid: %s\n", nisname));
1044 /* Search the table. */
1046 if(!(result = nisp_get_nis_list(nisname, 0)))
1048 return False;
1051 ret = make_sam_from_nisresult(user, result);
1052 nis_freeresult(result);
1054 return ret;
1057 /*************************************************************************
1058 Routine to remove entry from the nisplus smbpasswd table
1059 *************************************************************************/
1060 BOOL pdb_delete_sam_account(char *sname)
1062 char *pfile = smb_passwd_table();
1063 pstring nisname;
1064 nis_result *result, *delresult;
1065 nis_object *obj;
1066 int i;
1068 if (!*pfile)
1070 DEBUG(0, ("no SMB password file set\n"));
1071 return False;
1074 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", sname, pfile);
1076 /* Search the table. */
1078 if( !(result = nisp_get_nis_list(nisname,
1079 MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
1080 EXPAND_NAME|HARD_LOOKUP))) {
1081 return False;
1084 if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
1085 /* User not found. */
1086 DEBUG(0,("user not found in NIS+\n"));
1087 nis_freeresult(result);
1088 return False;
1091 obj = NIS_RES_OBJECT(result);
1092 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s", sname, obj->zo_name,
1093 obj->zo_domain);
1095 DEBUG(10, ("removing name: %s\n", nisname));
1096 delresult = nis_remove_entry(nisname, obj,
1097 MASTER_ONLY|REM_MULTIPLE|ALL_RESULTS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
1099 nis_freeresult(result);
1101 if(delresult->status != NIS_SUCCESS) {
1102 DEBUG(0, ("NIS+ table update failed: %s %s\n",
1103 nisname, nis_sperrno(delresult->status)));
1104 nis_freeresult(delresult);
1105 return False;
1107 nis_freeresult(delresult);
1108 return True;
1111 /************************************************************************
1112 Routine to add an entry to the nisplus passwd file.
1113 *************************************************************************/
1114 BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
1116 int local_user = 0;
1117 char *pfile = smb_passwd_table();
1118 pstring pfiletmp;
1119 char *nisname;
1120 nis_result *result = NULL, *tblresult = NULL;
1121 nis_object new_obj, *obj;
1122 entry_col *ecol;
1123 int ta_maxcol;
1126 * 1. find user domain.
1127 * a. try nis search in passwd.org_dir - if found use domain from result.
1128 * b. try getpwnam. this may be needed if user is defined
1129 * in /etc/passwd file (or elsewere) and not in passwd.org_dir.
1130 * if found, use host default domain.
1131 * c. exit with False - no such user.
1133 * 2. add user
1134 * a. find smbpasswd table
1135 * search pfile in user domain if not found, try host default
1136 * domain.
1137 * b. smbpasswd domain is found, fill data and add entry.
1143 * Check if user is already there.
1145 safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
1147 if(pdb_get_username(newpwd) != NULL) {
1148 nisname = make_nisname_from_name(pdb_get_username(newpwd),
1149 pfiletmp);
1150 } else {
1151 return False;
1154 if(!(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
1155 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
1156 return False;
1158 if (result->status != NIS_SUCCESS &&
1159 result->status != NIS_NOTFOUND) {
1160 DEBUG(3, ( "nis_list failure: %s: %s\n",
1161 nisname, nis_sperrno(result->status)));
1162 nis_freeresult(result);
1163 return False;
1166 if (result->status == NIS_SUCCESS && NIS_RES_NUMOBJ(result) > 0)
1168 DEBUG(3, ("User already exists in NIS+ password db: %s\n",
1169 pfile));
1170 nis_freeresult(result);
1171 return False;
1174 nis_freeresult(result); /* no such user, free results */
1177 * check for user in unix password database. we need this to get
1178 * domain, where smbpasswd entry should be stored.
1181 #if 1 /* passwd and smbpasswd users should be in the same domain */
1182 nisname = make_nisname_from_name(pdb_get_username(newpwd),
1183 "passwd.org_dir");
1185 result = nisp_get_nis_list(nisname,
1186 MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
1187 EXPAND_NAME|HARD_LOOKUP);
1189 if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0)
1191 DEBUG(3, ("nis_list failure: %s: %s\n",
1192 nisname, nis_sperrno(result->status)));
1193 nis_freeresult(result);
1195 if (!sys_getpwnam(pdb_get_username(newpwd))) {
1196 /* no such user in system! */
1197 return False;
1200 * user is defined, but not in passwd.org_dir.
1202 local_user = 1;
1203 } else {
1204 safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
1205 safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1);
1206 safe_strcat(pfiletmp, NIS_RES_OBJECT(result)->zo_domain,
1207 sizeof(pfiletmp)-strlen(pfiletmp)-1);
1208 nis_freeresult(result); /* not needed any more */
1210 tblresult = nis_lookup(pfiletmp,
1211 MASTER_ONLY|FOLLOW_LINKS|\
1212 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
1215 if (local_user || tblresult->status != NIS_SUCCESS)
1218 * no user domain or
1219 * smbpasswd table not found in user domain, fallback to
1220 * default domain.
1222 if (!local_user) /* free previous failed search result */
1223 nis_freeresult(tblresult);
1224 #endif
1225 tblresult = nis_lookup(pfile, MASTER_ONLY|FOLLOW_LINKS|\
1226 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
1227 if (tblresult->status != NIS_SUCCESS)
1229 /* still nothing. bail out */
1230 nis_freeresult(tblresult);
1231 DEBUG(3, ( "nis_lookup failure: %s\n",
1232 nis_sperrno(tblresult->status)));
1233 return False;
1235 obj = NIS_RES_OBJECT(tblresult);
1236 /* we need full name for nis_add_entry() */
1237 slprintf(pfiletmp, sizeof(pfiletmp)-1, "%s.%s", obj->zo_name,
1238 obj->zo_domain);
1239 #if 1 /* matching } from previous #if */
1241 #endif
1243 memset((char *)&new_obj, 0, sizeof (new_obj));
1244 /* fill entry headers */
1245 /* we do not free these. */
1246 new_obj.zo_name = obj->zo_name;
1247 new_obj.zo_owner = obj->zo_owner;
1248 new_obj.zo_group = obj->zo_group;
1249 new_obj.zo_domain = obj->zo_domain;
1250 /* uints */
1251 new_obj.zo_access = obj->zo_access;
1252 new_obj.zo_ttl = obj->zo_ttl;
1254 new_obj.zo_data.zo_type = ENTRY_OBJ;
1255 new_obj.EN_data.en_type = obj->TA_data.ta_type;
1257 ta_maxcol = obj->TA_data.ta_maxcol;
1259 if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
1260 DEBUG(0, ("memory allocation failure\n"));
1261 nis_freeresult(tblresult);
1262 return False;
1265 memset((char *)ecol, 0, ta_maxcol*sizeof (entry_col));
1266 new_obj.EN_data.en_cols.en_cols_val = ecol;
1267 new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
1269 init_nisp_from_sam(&new_obj, newpwd, NULL);
1271 DEBUG(10, ( "add NIS+ entry: %s\n", nisname));
1272 result = nis_add_entry(pfiletmp, &new_obj, 0);
1274 free(ecol); /* free allocated entry space */
1276 if (result->status != NIS_SUCCESS)
1278 DEBUG(3, ( "NIS+ table update failed: %s\n",
1279 nisname, nis_sperrno(result->status)));
1280 nis_freeresult(tblresult);
1281 nis_freeresult(result);
1282 return False;
1285 nis_freeresult(tblresult);
1286 nis_freeresult(result);
1288 return True;
1291 /************************************************************************
1292 Routine to modify the nisplus passwd entry.
1293 ************************************************************************/
1294 BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override)
1296 nis_result *result, *addresult;
1297 nis_object *obj;
1298 nis_object new_obj;
1299 entry_col *ecol;
1300 int ta_maxcol;
1301 char *pfile = smb_passwd_table();
1302 pstring nisname;
1303 int i;
1305 if (!*pfile)
1307 DEBUG(0, ("no SMB password file set\n"));
1308 return False;
1311 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s",
1312 pdb_get_username(newpwd), pfile);
1314 DEBUG(10, ("search by name: %s\n", nisname));
1316 /* Search the table. */
1318 if( !(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
1319 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
1320 return False;
1323 if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
1324 /* User not found. */
1325 DEBUG(0,("user not found in NIS+\n"));
1326 nis_freeresult(result);
1327 return False;
1330 obj = NIS_RES_OBJECT(result);
1331 DEBUG(6,("entry found in %s\n", obj->zo_domain));
1333 /* we must create new stub object with EN_MODIFIED flag.
1334 this is because obj from result is going to be freed and
1335 we do not want to break it or cause memory leaks or corruption.
1338 memmove((char *)&new_obj, obj, sizeof (new_obj));
1339 ta_maxcol = obj->TA_data.ta_maxcol;
1341 if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
1342 DEBUG(0, ("memory allocation failure\n"));
1343 nis_freeresult(result);
1344 return False;
1347 memmove((char *)ecol, obj->EN_data.en_cols.en_cols_val,
1348 ta_maxcol*sizeof (entry_col));
1349 new_obj.EN_data.en_cols.en_cols_val = ecol;
1350 new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
1352 if ( init_nisp_from_sam(&new_obj, newpwd, obj) == True ) {
1353 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s",
1354 pdb_get_username(newpwd), obj->zo_name, obj->zo_domain);
1356 DEBUG(10, ("NIS+ table update: %s\n", nisname));
1357 addresult =
1358 nis_modify_entry(nisname, &new_obj,
1359 MOD_SAMEOBJ | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP);
1361 if(addresult->status != NIS_SUCCESS) {
1362 DEBUG(0, ("NIS+ table update failed: %s %s\n",
1363 nisname, nis_sperrno(addresult->status)));
1364 nis_freeresult(addresult);
1365 nis_freeresult(result);
1366 free(ecol);
1367 return False;
1370 DEBUG(6,("password changed\n"));
1371 nis_freeresult(addresult);
1372 } else {
1373 DEBUG(6,("nothing to change!\n"));
1376 free(ecol);
1377 nis_freeresult(result);
1379 return True;
1382 #else
1383 void nisplus_dummy_function(void);
1384 void nisplus_dummy_function(void) { } /* stop some compilers complaining */
1385 #endif /* WITH_NISPLUSSAM */