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
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)
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
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.
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.
41 #if defined(GROUP_OBJ)
47 #include <rpcsvc/nis.h>
49 extern int DEBUGLEVEL;
57 static struct nisp_enum_info global_nisp_ent;
58 static VOLATILE sig_atomic_t gotalarm;
60 /***************************************************************
62 the fields for the NIS+ table, generated from mknissmbpwtbl.sh, are:
91 ****************************************************************/
95 #define NPF_USER_RID 2
96 #define NPF_SMB_GRPID 3
97 #define NPF_GROUP_RID 4
101 #define NPF_LOGON_T 8
102 #define NPF_LOGOFF_T 9
103 #define NPF_KICK_T 10
104 #define NPF_PWDLSET_T 11
105 #define NPF_PWDCCHG_T 12
106 #define NPF_PWDMCHG_T 13
107 #define NPF_FULL_NAME 14
108 #define NPF_HOME_DIR 15
109 #define NPF_DIR_DRIVE 16
110 #define NPF_LOGON_SCRIPT 17
111 #define NPF_PROFILE_PATH 18
112 #define NPF_ACCT_DESC 19
113 #define NPF_WORKSTATIONS 20
116 /***************************************************************
117 Signal function to tell us we timed out.
118 ****************************************************************/
119 static void gotalarm_sig(void)
124 /***************************************************************
125 make_nisname_from_user_rid
126 ****************************************************************/
127 static char *make_nisname_from_user_rid(uint32 rid, char *pfile)
129 static pstring nisname;
131 safe_strcpy(nisname, "[user_rid=", sizeof(nisname)-1);
132 slprintf(nisname, sizeof(nisname)-1, "%s%d", nisname, rid);
133 safe_strcat(nisname, "],", sizeof(nisname)-strlen(nisname)-1);
134 safe_strcat(nisname, pfile, sizeof(nisname)-strlen(nisname)-1);
139 /***************************************************************
140 make_nisname_from_uid
141 ****************************************************************/
142 static char *make_nisname_from_uid(int uid, char *pfile)
144 static pstring nisname;
146 safe_strcpy(nisname, "[uid=", sizeof(nisname)-1);
147 slprintf(nisname, sizeof(nisname)-1, "%s%d", nisname, uid);
148 safe_strcat(nisname, "],", sizeof(nisname)-strlen(nisname)-1);
149 safe_strcat(nisname, pfile, sizeof(nisname)-strlen(nisname)-1);
154 /***************************************************************
155 make_nisname_from_name
156 ****************************************************************/
157 static char *make_nisname_from_name(const char *user_name, char *pfile)
159 static pstring nisname;
161 safe_strcpy(nisname, "[name=", sizeof(nisname)-1);
162 safe_strcat(nisname, user_name, sizeof(nisname) - strlen(nisname) - 1);
163 safe_strcat(nisname, "],", sizeof(nisname)-strlen(nisname)-1);
164 safe_strcat(nisname, pfile, sizeof(nisname)-strlen(nisname)-1);
169 /*************************************************************************
170 gets a NIS+ attribute
171 *************************************************************************/
172 static void get_single_attribute(const nis_object *new_obj, int col,
177 if (new_obj == NULL || val == NULL) return;
179 entry_len = ENTRY_LEN(new_obj, col);
185 safe_strcpy(val, ENTRY_VAL(new_obj, col), len-1);
188 /************************************************************************
189 makes a struct sam_passwd from a NIS+ object.
190 ************************************************************************/
191 static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, const nis_object *obj)
194 pstring full_name; /* this must be translated to dos code page */
195 pstring acct_desc; /* this must be translated to dos code page */
196 pstring home_dir; /* set default value from smb.conf for user */
197 pstring home_drive; /* set default value from smb.conf for user */
198 pstring logon_script; /* set default value from smb.conf for user */
199 pstring profile_path; /* set default value from smb.conf for user */
202 unsigned char smbpwd[16];
203 unsigned char smbntpwd[16];
207 * time values. note: this code assumes 32bit time_t!
210 /* Don't change these timestamp settings without a good reason. They are
211 important for NT member server compatibility. */
213 pdb_set_logon_time(pw_buf, (time_t)0);
214 ptr = (uchar *)ENTRY_VAL(obj, NPF_LOGON_T);
215 if(ptr && *ptr && (StrnCaseCmp(ptr, "LNT-", 4)==0)) {
218 for(i = 0; i < 8; i++) {
219 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
223 pdb_set_logon_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
227 pdb_set_logoff_time(pw_buf, get_time_t_max());
228 ptr = (uchar *)ENTRY_VAL(obj, NPF_LOGOFF_T);
229 if(ptr && *ptr && (StrnCaseCmp(ptr, "LOT-", 4)==0)) {
232 for(i = 0; i < 8; i++) {
233 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
237 pdb_set_logoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
241 pdb_set_kickoff_time(pw_buf, get_time_t_max());
242 ptr = (uchar *)ENTRY_VAL(obj, NPF_KICK_T);
243 if(ptr && *ptr && (StrnCaseCmp(ptr, "KOT-", 4)==0)) {
246 for(i = 0; i < 8; i++) {
247 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
251 pdb_set_kickoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
255 pdb_set_pass_last_set_time(pw_buf, (time_t)0);
256 ptr = (uchar *)ENTRY_VAL(obj, NPF_PWDLSET_T);
257 if(ptr && *ptr && (StrnCaseCmp(ptr, "LCT-", 4)==0)) {
260 for(i = 0; i < 8; i++) {
261 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
265 pdb_set_pass_last_set_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
269 pdb_set_pass_can_change_time(pw_buf, (time_t)0);
270 ptr = (uchar *)ENTRY_VAL(obj, NPF_PWDCCHG_T);
271 if(ptr && *ptr && (StrnCaseCmp(ptr, "CCT-", 4)==0)) {
274 for(i = 0; i < 8; i++) {
275 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
279 pdb_set_pass_can_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
283 pdb_set_pass_must_change_time(pw_buf, get_time_t_max()); /* Password never expires. */
284 ptr = (uchar *)ENTRY_VAL(obj, NPF_PWDMCHG_T);
285 if(ptr && *ptr && (StrnCaseCmp(ptr, "MCT-", 4)==0)) {
288 for(i = 0; i < 8; i++) {
289 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
293 pdb_set_pass_must_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
298 pdb_set_username(pw_buf, ENTRY_VAL(obj, NPF_NAME));
299 pdb_set_domain(pw_buf, lp_workgroup());
300 /* pdb_set_nt_username() -- cant set it here... */
302 get_single_attribute(obj, NPF_FULL_NAME, full_name, sizeof(pstring));
303 unix_to_dos(full_name, True);
304 pdb_set_fullname(pw_buf, full_name);
306 pdb_set_acct_ctrl(pw_buf, pdb_decode_acct_ctrl(ENTRY_VAL(obj,
309 get_single_attribute(obj, NPF_ACCT_DESC, acct_desc, sizeof(pstring));
310 unix_to_dos(acct_desc, True);
311 pdb_set_acct_desc(pw_buf, acct_desc);
313 pdb_set_workstations(pw_buf, ENTRY_VAL(obj, NPF_WORKSTATIONS));
314 pdb_set_munged_dial(pw_buf, NULL);
316 pdb_set_uid(pw_buf, atoi(ENTRY_VAL(obj, NPF_UID)));
317 pdb_set_gid(pw_buf, atoi(ENTRY_VAL(obj, NPF_SMB_GRPID)));
318 pdb_set_user_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_USER_RID)));
319 pdb_set_group_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_GROUP_RID)));
321 /* values, must exist for user */
322 if( !(pdb_get_acct_ctrl(pw_buf) & ACB_WSTRUST) ) {
324 get_single_attribute(obj, NPF_HOME_DIR, home_dir, sizeof(pstring));
325 if( !(home_dir && *home_dir) )
326 pstrcpy(home_dir, lp_logon_home());
327 pdb_set_homedir(pw_buf, home_dir);
329 get_single_attribute(obj, NPF_DIR_DRIVE, home_drive, sizeof(pstring));
330 if( !(home_drive && *home_drive) )
331 pstrcpy(home_drive, lp_logon_drive());
332 pdb_set_dir_drive(pw_buf, home_drive);
334 get_single_attribute(obj, NPF_LOGON_SCRIPT, logon_script,
336 if( !(logon_script && *logon_script) )
337 pstrcpy(logon_script, lp_logon_script());
338 pdb_set_logon_script(pw_buf, logon_script);
340 get_single_attribute(obj, NPF_PROFILE_PATH, profile_path,
342 if( !(profile_path && *profile_path) )
343 pstrcpy(profile_path, lp_logon_path());
344 pdb_set_profile_path(pw_buf, profile_path);
346 /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
347 pdb_set_group_rid (pw_buf, DOMAIN_GROUP_RID_USERS);
350 /* Check the lanman password column. */
351 ptr = (char *)ENTRY_VAL(obj, NPF_LMPWD);
352 pdb_set_lanman_passwd(pw_buf, NULL);
354 if (!strncasecmp(ptr, "NO PASSWORD", 11)) {
355 pdb_set_acct_ctrl(pw_buf, pdb_get_acct_ctrl(pw_buf) | ACB_PWNOTREQ);
357 if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbpwd)) {
358 DEBUG(0, ("malformed LM pwd entry: %s.\n",
359 pdb_get_username(pw_buf)));
362 pdb_set_lanman_passwd(pw_buf, smbpwd);
365 /* Check the NT password column. */
366 ptr = ENTRY_VAL(obj, NPF_NTPWD);
367 pdb_set_nt_passwd(pw_buf, NULL);
369 if (!(pdb_get_acct_ctrl(pw_buf) & ACB_PWNOTREQ) &&
370 strncasecmp(ptr, "NO PASSWORD", 11)) {
371 if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbntpwd)) {
372 DEBUG(0, ("malformed NT pwd entry: uid = %d.\n",
373 pdb_get_uid(pw_buf)));
376 pdb_set_nt_passwd(pw_buf, smbntpwd);
379 pdb_set_unknown_3(pw_buf, 0xffffff); /* don't know */
380 pdb_set_logons_divs(pw_buf, 168); /* hours per week */
382 if( (hours_len = ENTRY_LEN(obj, NPF_HOURS)) == 21 ) {
383 memcpy(hours, ENTRY_VAL(obj, NPF_HOURS), hours_len);
385 hours_len = 21; /* 21 times 8 bits = 168 */
386 /* available at all hours */
387 memset(hours, 0xff, hours_len);
389 pdb_set_hours_len(pw_buf, hours_len);
390 pdb_set_hours(pw_buf, hours);
392 pdb_set_unknown_5(pw_buf, 0x00020000); /* don't know */
393 pdb_set_unknown_6(pw_buf, 0x000004ec); /* don't know */
398 /************************************************************************
399 makes a struct sam_passwd from a NIS+ result.
400 ************************************************************************/
401 static BOOL make_sam_from_nisresult(SAM_ACCOUNT *pw_buf, const nis_result *result)
403 if (pw_buf == NULL || result == NULL) return False;
405 if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND)
407 DEBUG(0, ("NIS+ lookup failure: %s\n",
408 nis_sperrno(result->status)));
412 /* User not found. */
413 if (NIS_RES_NUMOBJ(result) <= 0)
415 DEBUG(10, ("user not found in NIS+\n"));
419 if (NIS_RES_NUMOBJ(result) > 1)
421 DEBUG(10, ("WARNING: Multiple entries for user in NIS+ table!\n"));
424 /* Grab the first hit. */
425 return make_sam_from_nisp_object(pw_buf, &NIS_RES_OBJECT(result)[0]);
428 /*************************************************************************
429 sets a NIS+ attribute
430 *************************************************************************/
431 static void set_single_attribute(nis_object *new_obj, int col,
432 const char *val, int len, int flags)
434 if (new_obj == NULL) return;
436 ENTRY_VAL(new_obj, col) = val;
437 ENTRY_LEN(new_obj, col) = len+1;
441 new_obj->EN_data.en_cols.en_cols_val[col].ec_flags = flags;
445 /***************************************************************
446 copy or modify nis object. this object is used to add or update
448 ****************************************************************/
449 static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass,
453 * Fill nis_object for entry add or update.
454 * if we are updateing, we have to find out differences and set
455 * EN_MODIFIED flag. also set need_to_modify to trigger
456 * nis_modify_entry() call in pdb_update_sam_account().
460 * if (modify) get data from nis_object, compare and store if
461 * different + set EN_MODIFIED and need_to_modify
465 BOOL need_to_modify = False;
466 const char *name = pdb_get_username(sampass); /* from SAM */
467 /* these must be static or allocate and free entry columns! */
468 static fstring uid; /* from SAM */
469 static fstring user_rid; /* from SAM */
470 static fstring gid; /* from SAM */
471 static fstring group_rid; /* from SAM */
472 char *acb; /* from SAM */
473 static fstring smb_passwd; /* from SAM */
474 static fstring smb_nt_passwd; /* from SAM */
475 static fstring logon_t; /* from SAM */
476 static fstring logoff_t; /* from SAM */
477 static fstring kickoff_t; /* from SAM */
478 static fstring pwdlset_t; /* from SAM */
479 static fstring pwdlchg_t; /* from SAM */
480 static fstring pwdmchg_t; /* from SAM */
481 static fstring full_name; /* from SAM */
482 static fstring acct_desc; /* from SAM */
483 static char empty[1]; /* just an empty string */
485 slprintf(uid, sizeof(uid)-1, "%u", pdb_get_uid(sampass));
486 slprintf(user_rid, sizeof(user_rid)-1, "%u",
487 pdb_get_user_rid(sampass)? pdb_get_user_rid(sampass):
488 pdb_uid_to_user_rid(pdb_get_uid(sampass)));
489 slprintf(gid, sizeof(gid)-1, "%u", pdb_get_gid(sampass));
495 rid=pdb_get_group_rid(sampass);
498 if (get_group_map_from_gid(pdb_get_gid(sampass), &map, MAPPING_WITHOUT_PRIV)) {
499 sid_peek_rid(&map.sid, &rid);
501 rid=pdb_gid_to_group_rid(pdb_get_gid(sampass));
504 slprintf(group_rid, sizeof(group_rid)-1, "%u", rid);
507 acb = pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sampass),
508 NEW_PW_FORMAT_SPACE_PADDED_LEN);
509 pdb_sethexpwd (smb_passwd, pdb_get_lanman_passwd(sampass),
510 pdb_get_acct_ctrl(sampass));
511 pdb_sethexpwd (smb_nt_passwd, pdb_get_nt_passwd(sampass),
512 pdb_get_acct_ctrl(sampass));
513 slprintf(logon_t, 13, "LNT-%08X",
514 (uint32)pdb_get_logon_time(sampass));
515 slprintf(logoff_t, 13, "LOT-%08X",
516 (uint32)pdb_get_logoff_time(sampass));
517 slprintf(kickoff_t, 13, "KOT-%08X",
518 (uint32)pdb_get_kickoff_time(sampass));
519 slprintf(pwdlset_t, 13, "LCT-%08X",
520 (uint32)pdb_get_pass_last_set_time(sampass));
521 slprintf(pwdlchg_t, 13, "CCT-%08X",
522 (uint32)pdb_get_pass_can_change_time(sampass));
523 slprintf(pwdmchg_t, 13, "MCT-%08X",
524 (uint32)pdb_get_pass_must_change_time(sampass));
525 safe_strcpy(full_name, pdb_get_fullname(sampass), sizeof(full_name)-1);
526 dos_to_unix(full_name, True);
527 safe_strcpy(acct_desc, pdb_get_acct_desc(sampass), sizeof(acct_desc)-1);
528 dos_to_unix(acct_desc, True);
532 if(strcmp(ENTRY_VAL(old, NPF_NAME), name))
534 need_to_modify = True;
535 set_single_attribute(obj, NPF_NAME, name, strlen(name),
541 if(pdb_get_uid(sampass) != -1) {
542 if(!ENTRY_VAL(old, NPF_UID) || strcmp(ENTRY_VAL(old, NPF_UID), uid))
544 need_to_modify = True;
545 set_single_attribute(obj, NPF_UID, uid,
546 strlen(uid), EN_MODIFIED);
551 if (pdb_get_user_rid(sampass)) {
552 if(!ENTRY_VAL(old, NPF_USER_RID) ||
553 strcmp(ENTRY_VAL(old, NPF_USER_RID), user_rid) ) {
554 need_to_modify = True;
555 set_single_attribute(obj, NPF_USER_RID, user_rid,
556 strlen(user_rid), EN_MODIFIED);
561 if (pdb_get_gid(sampass) != -1) {
562 if(!ENTRY_VAL(old, NPF_SMB_GRPID) ||
563 strcmp(ENTRY_VAL(old, NPF_SMB_GRPID), gid) ) {
564 need_to_modify = True;
565 set_single_attribute(obj, NPF_SMB_GRPID, gid,
566 strlen(gid), EN_MODIFIED);
571 if (pdb_get_group_rid(sampass)) {
572 if(!ENTRY_VAL(old, NPF_GROUP_RID) ||
573 strcmp(ENTRY_VAL(old, NPF_GROUP_RID), group_rid) ) {
574 need_to_modify = True;
575 set_single_attribute(obj, NPF_GROUP_RID, group_rid,
576 strlen(group_rid), EN_MODIFIED);
581 if (!ENTRY_VAL(old, NPF_ACB) ||
582 strcmp(ENTRY_VAL(old, NPF_ACB), acb)) {
583 need_to_modify = True;
584 set_single_attribute(obj, NPF_ACB, acb, strlen(acb), EN_MODIFIED);
588 if(!ENTRY_VAL(old, NPF_LMPWD) ||
589 strcmp(ENTRY_VAL(old, NPF_LMPWD), smb_passwd) ) {
590 need_to_modify = True;
591 set_single_attribute(obj, NPF_LMPWD, smb_passwd,
592 strlen(smb_passwd), EN_CRYPT|EN_MODIFIED);
596 if(!ENTRY_VAL(old, NPF_NTPWD) ||
597 strcmp(ENTRY_VAL(old, NPF_NTPWD), smb_nt_passwd) ) {
598 need_to_modify = True;
599 set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd,
600 strlen(smb_nt_passwd), EN_CRYPT|EN_MODIFIED);
604 if( pdb_get_logon_time(sampass) &&
605 (!ENTRY_VAL(old, NPF_LOGON_T) ||
606 strcmp(ENTRY_VAL(old, NPF_LOGON_T), logon_t ))) {
607 need_to_modify = True;
608 set_single_attribute(obj, NPF_LOGON_T, logon_t,
609 strlen(logon_t), EN_MODIFIED);
613 if( pdb_get_logoff_time(sampass) &&
614 (!ENTRY_VAL(old, NPF_LOGOFF_T) ||
615 strcmp(ENTRY_VAL(old, NPF_LOGOFF_T), logoff_t))) {
616 need_to_modify = True;
617 set_single_attribute(obj, NPF_LOGOFF_T, logoff_t,
618 strlen(logoff_t), EN_MODIFIED);
622 if( pdb_get_kickoff_time(sampass) &&
623 (!ENTRY_VAL(old, NPF_KICK_T) ||
624 strcmp(ENTRY_VAL(old, NPF_KICK_T), kickoff_t))) {
625 need_to_modify = True;
626 set_single_attribute(obj, NPF_KICK_T, kickoff_t,
627 strlen(kickoff_t), EN_MODIFIED);
631 if( pdb_get_pass_last_set_time(sampass) &&
632 (!ENTRY_VAL(old, NPF_PWDLSET_T) ||
633 strcmp(ENTRY_VAL(old, NPF_PWDLSET_T), pwdlset_t))) {
634 need_to_modify = True;
635 set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t,
636 strlen(pwdlset_t), EN_MODIFIED);
640 if( pdb_get_pass_can_change_time(sampass) &&
641 (!ENTRY_VAL(old, NPF_PWDCCHG_T) ||
642 strcmp(ENTRY_VAL(old, NPF_PWDCCHG_T), pwdlchg_t))) {
643 need_to_modify = True;
644 set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t,
645 strlen(pwdlchg_t), EN_MODIFIED);
649 if( pdb_get_pass_must_change_time(sampass) &&
650 (!ENTRY_VAL(old, NPF_PWDMCHG_T) ||
651 strcmp(ENTRY_VAL(old, NPF_PWDMCHG_T), pwdmchg_t))) {
652 need_to_modify = True;
653 set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t,
654 strlen(pwdmchg_t), EN_MODIFIED);
658 /* must support set, unset and change */
659 if ( (pdb_get_fullname(sampass) &&
660 !ENTRY_VAL(old, NPF_FULL_NAME)) ||
661 (ENTRY_VAL(old, NPF_FULL_NAME) &&
662 !pdb_get_fullname(sampass)) ||
663 (ENTRY_VAL(old, NPF_FULL_NAME) &&
664 pdb_get_fullname(sampass) &&
665 strcmp( ENTRY_VAL(old, NPF_FULL_NAME), full_name ))) {
666 need_to_modify = True;
667 set_single_attribute(obj, NPF_FULL_NAME, full_name,
668 strlen(full_name), EN_MODIFIED);
672 /* must support set, unset and change */
673 if( (pdb_get_homedir(sampass) &&
674 !ENTRY_VAL(old, NPF_HOME_DIR)) ||
675 (ENTRY_VAL(old, NPF_HOME_DIR) &&
676 !pdb_get_homedir(sampass)) ||
677 (ENTRY_VAL(old, NPF_HOME_DIR) &&
678 pdb_get_homedir(sampass) &&
679 strcmp( ENTRY_VAL(old, NPF_HOME_DIR),
680 pdb_get_homedir(sampass)))) {
681 need_to_modify = True;
682 set_single_attribute(obj, NPF_HOME_DIR, pdb_get_homedir(sampass),
683 strlen(pdb_get_homedir(sampass)), EN_MODIFIED);
687 /* must support set, unset and change */
688 if( (pdb_get_dirdrive(sampass) &&
689 !ENTRY_VAL(old, NPF_DIR_DRIVE)) ||
690 (ENTRY_VAL(old, NPF_DIR_DRIVE) &&
691 !pdb_get_dirdrive(sampass)) ||
692 (ENTRY_VAL(old, NPF_DIR_DRIVE) &&
693 pdb_get_dirdrive(sampass) &&
694 strcmp( ENTRY_VAL(old, NPF_DIR_DRIVE),
695 pdb_get_dirdrive(sampass)))) {
696 need_to_modify = True;
697 set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dirdrive(sampass),
698 strlen(pdb_get_dirdrive(sampass)), EN_MODIFIED);
702 /* must support set, unset and change */
703 if( (pdb_get_logon_script(sampass) &&
704 !ENTRY_VAL(old, NPF_LOGON_SCRIPT) ||
705 (ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
706 !pdb_get_logon_script(sampass)) ||
707 ( ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
708 pdb_get_logon_script(sampass) &&
709 strcmp( ENTRY_VAL(old, NPF_LOGON_SCRIPT),
710 pdb_get_logon_script(sampass))))) {
711 need_to_modify = True;
712 set_single_attribute(obj, NPF_LOGON_SCRIPT,
713 pdb_get_logon_script(sampass),
714 strlen(pdb_get_logon_script(sampass)),
719 /* must support set, unset and change */
720 if( (pdb_get_profile_path(sampass) &&
721 !ENTRY_VAL(old, NPF_PROFILE_PATH)) ||
722 (ENTRY_VAL(old, NPF_PROFILE_PATH) &&
723 !pdb_get_profile_path(sampass)) ||
724 (ENTRY_VAL(old, NPF_PROFILE_PATH) &&
725 pdb_get_profile_path(sampass) &&
726 strcmp( ENTRY_VAL(old, NPF_PROFILE_PATH),
727 pdb_get_profile_path(sampass) ) )) {
728 need_to_modify = True;
729 set_single_attribute(obj, NPF_PROFILE_PATH,
730 pdb_get_profile_path(sampass),
731 strlen(pdb_get_profile_path(sampass)),
736 /* must support set, unset and change */
737 if( (pdb_get_acct_desc(sampass) &&
738 !ENTRY_VAL(old, NPF_ACCT_DESC)) ||
739 (ENTRY_VAL(old, NPF_ACCT_DESC) &&
740 !pdb_get_acct_desc(sampass)) ||
741 (ENTRY_VAL(old, NPF_ACCT_DESC) &&
742 pdb_get_acct_desc(sampass) &&
743 strcmp( ENTRY_VAL(old, NPF_ACCT_DESC), acct_desc ) )) {
744 need_to_modify = True;
745 set_single_attribute(obj, NPF_ACCT_DESC, acct_desc,
746 strlen(acct_desc), EN_MODIFIED);
750 /* must support set, unset and change */
751 if ( (pdb_get_workstations(sampass) &&
752 !ENTRY_VAL(old, NPF_WORKSTATIONS) ) ||
753 (ENTRY_VAL(old, NPF_WORKSTATIONS) &&
754 !pdb_get_workstations(sampass)) ||
755 (ENTRY_VAL(old, NPF_WORKSTATIONS) &&
756 pdb_get_workstations(sampass)) &&
757 strcmp( ENTRY_VAL(old, NPF_WORKSTATIONS),
758 pdb_get_workstations(sampass))) {
759 need_to_modify = True;
760 set_single_attribute(obj, NPF_WORKSTATIONS,
761 pdb_get_workstations(sampass),
762 strlen(pdb_get_workstations(sampass)),
767 if ((pdb_get_hours_len(sampass) != ENTRY_LEN(old, NPF_HOURS)) ||
768 memcmp(pdb_get_hours(sampass), ENTRY_VAL(old, NPF_HOURS),
769 ENTRY_LEN(old, NPF_HOURS))) {
770 need_to_modify = True;
771 /* set_single_attribute will add 1 for len ... */
772 set_single_attribute(obj, NPF_HOURS, pdb_get_hours(sampass),
773 pdb_get_hours_len(sampass)-1, EN_MODIFIED);
776 const char *homedir, *dirdrive, *logon_script, *profile_path, *workstations;
778 *empty = '\0'; /* empty string */
780 set_single_attribute(obj, NPF_NAME, name, strlen(name), 0);
781 set_single_attribute(obj, NPF_UID, uid, strlen(uid), 0);
782 set_single_attribute(obj, NPF_USER_RID, user_rid,
783 strlen(user_rid), 0);
784 set_single_attribute(obj, NPF_SMB_GRPID, gid, strlen(gid), 0);
785 set_single_attribute(obj, NPF_GROUP_RID, group_rid,
786 strlen(group_rid), 0);
787 set_single_attribute(obj, NPF_ACB, acb, strlen(acb), 0);
788 set_single_attribute(obj, NPF_LMPWD, smb_passwd,
789 strlen(smb_passwd), EN_CRYPT);
790 set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd,
791 strlen(smb_nt_passwd), EN_CRYPT);
792 set_single_attribute(obj, NPF_LOGON_T, logon_t,
794 set_single_attribute(obj, NPF_LOGOFF_T, logoff_t,
795 strlen(logoff_t), 0);
796 set_single_attribute(obj, NPF_KICK_T, kickoff_t,
797 strlen(kickoff_t),0);
798 set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t,
799 strlen(pwdlset_t), 0);
800 set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t,
801 strlen(pwdlchg_t), 0);
802 set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t,
803 strlen(pwdmchg_t), 0);
804 set_single_attribute(obj, NPF_FULL_NAME ,
805 full_name, strlen(full_name), 0);
807 if(!(homedir = pdb_get_homedir(sampass)))
810 set_single_attribute(obj, NPF_HOME_DIR,
811 homedir, strlen(homedir), 0);
813 if(!(dirdrive = pdb_get_dirdrive(sampass)))
816 set_single_attribute(obj, NPF_DIR_DRIVE,
817 dirdrive, strlen(dirdrive), 0);
819 if(!(logon_script = pdb_get_logon_script(sampass)))
820 logon_script = empty;
822 set_single_attribute(obj, NPF_LOGON_SCRIPT,
823 logon_script, strlen(logon_script), 0);
825 if(!(profile_path = pdb_get_profile_path(sampass)))
826 profile_path = empty;
828 set_single_attribute(obj, NPF_PROFILE_PATH,
829 profile_path, strlen(profile_path), 0);
831 set_single_attribute(obj, NPF_ACCT_DESC,
832 acct_desc, strlen(acct_desc), 0);
834 if(!(workstations = pdb_get_workstations(sampass)))
835 workstations = empty;
837 set_single_attribute(obj, NPF_WORKSTATIONS,
838 workstations, strlen(workstations), 0);
840 /* set_single_attribute will add 1 for len ... */
841 set_single_attribute(obj, NPF_HOURS,
842 pdb_get_hours(sampass),
843 pdb_get_hours_len(sampass)-1, 0);
846 return need_to_modify;
849 /***************************************************************
850 calls nis_list, returns results.
851 ****************************************************************/
852 static nis_result *nisp_get_nis_list(const char *nis_name, uint_t flags)
858 flags = FOLLOW_LINKS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP;
860 for(i = 0; i<2;i++ ) {
861 alarm(60); /* hopefully ok for long searches */
862 result = nis_list(nis_name, flags,NULL,NULL);
865 CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
869 DEBUG(0,("NIS+ lookup time out\n"));
870 nis_freeresult(result);
873 if( !(flags & MASTER_ONLY) && NIS_RES_NUMOBJ(result) <= 0 ) {
874 /* nis replicas are not in sync perhaps?
875 * this can happen, if account was just added.
877 DEBUG(10,("will try master only\n"));
878 nis_freeresult(result);
879 flags |= MASTER_ONLY;
886 /***************************************************************
887 Start to enumerate the nisplus passwd list.
888 ****************************************************************/
889 BOOL pdb_setsampwent(BOOL update)
891 char *sp, * p = lp_smb_passwd_file();
894 if( (sp = strrchr( p, '/' )) )
895 safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1);
897 safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1);
898 safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1);
900 pdb_endsampwent(); /* just in case */
901 global_nisp_ent.result = nisp_get_nis_list( pfiletmp, 0 );
902 global_nisp_ent.enum_entry = 0;
903 return global_nisp_ent.result != NULL ? True : False;
906 /***************************************************************
907 End enumeration of the nisplus passwd list.
908 ****************************************************************/
909 void pdb_endsampwent(void)
911 if( global_nisp_ent.result )
912 nis_freeresult(global_nisp_ent.result);
913 global_nisp_ent.result = NULL;
914 global_nisp_ent.enum_entry = 0;
917 /*************************************************************************
918 Routine to return the next entry in the nisplus passwd list.
919 *************************************************************************/
920 BOOL pdb_getsampwent(SAM_ACCOUNT *user)
922 int enum_entry = (int)(global_nisp_ent.enum_entry);
923 nis_result *result = global_nisp_ent.result;
926 DEBUG(0,("SAM_ACCOUNT is NULL.\n"));
930 if (result == NULL ||
931 enum_entry < 0 || enum_entry >= (NIS_RES_NUMOBJ(result) - 1))
936 if(!make_sam_from_nisp_object(user, &NIS_RES_OBJECT(result)[enum_entry]) )
938 DEBUG(0,("Bad SAM_ACCOUNT entry returned from NIS+!\n"));
941 (int)(global_nisp_ent.enum_entry)++;
945 /*************************************************************************
946 Routine to search the nisplus passwd file for an entry matching the username
947 *************************************************************************/
948 BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname)
950 /* Static buffers we will return. */
951 nis_result *result = NULL;
954 char *pfile = lp_smb_passwd_file();
959 DEBUG(0, ("No SMB password file set\n"));
962 if( strrchr( pfile, '/') )
963 pfile = strrchr( pfile, '/') + 1;
965 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir", sname, pfile);
966 DEBUG(10, ("search by nisname: %s\n", nisname));
968 /* Search the table. */
970 if(!(result = nisp_get_nis_list(nisname, 0)))
975 ret = make_sam_from_nisresult(user, result);
976 nis_freeresult(result);
981 /*************************************************************************
982 Routine to search the nisplus passwd file for an entry matching the username
983 *************************************************************************/
984 BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
989 char *sp, *p = lp_smb_passwd_file();
994 DEBUG(0, ("no SMB password file set\n"));
998 if( (sp = strrchr( p, '/' )) )
999 safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1);
1001 safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1);
1002 safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1);
1004 nisname = make_nisname_from_user_rid(rid, pfiletmp);
1006 DEBUG(10, ("search by rid: %s\n", nisname));
1008 /* Search the table. */
1010 if(!(result = nisp_get_nis_list(nisname, 0)))
1015 ret = make_sam_from_nisresult(user, result);
1016 nis_freeresult(result);
1021 /*************************************************************************
1022 Routine to search the nisplus passwd file for an entry matching the username
1023 *************************************************************************/
1024 BOOL pdb_getsampwuid(SAM_ACCOUNT * user, uid_t uid)
1029 char *sp, *p = lp_smb_passwd_file();
1034 DEBUG(0, ("no SMB password file set\n"));
1038 if( (sp = strrchr( p, '/' )) )
1039 safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1);
1041 safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1);
1042 safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1);
1044 nisname = make_nisname_from_uid(uid, pfiletmp);
1046 DEBUG(10, ("search by uid: %s\n", nisname));
1048 /* Search the table. */
1050 if(!(result = nisp_get_nis_list(nisname, 0)))
1055 ret = make_sam_from_nisresult(user, result);
1056 nis_freeresult(result);
1061 /*************************************************************************
1062 Routine to remove entry from the nisplus smbpasswd table
1063 *************************************************************************/
1064 BOOL pdb_delete_sam_account(const char *sname)
1066 char *pfile = lp_smb_passwd_file();
1068 nis_result *result, *delresult;
1074 DEBUG(0, ("no SMB password file set\n"));
1077 if( strrchr( pfile, '/') )
1078 pfile = strrchr( pfile, '/') + 1;
1080 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir", sname, pfile);
1082 /* Search the table. */
1084 if( !(result = nisp_get_nis_list(nisname,
1085 MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
1086 EXPAND_NAME|HARD_LOOKUP))) {
1090 if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
1091 /* User not found. */
1092 DEBUG(0,("user not found in NIS+\n"));
1093 nis_freeresult(result);
1097 obj = NIS_RES_OBJECT(result);
1098 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s", sname, obj->zo_name,
1101 DEBUG(10, ("removing name: %s\n", nisname));
1102 delresult = nis_remove_entry(nisname, obj,
1103 MASTER_ONLY|REM_MULTIPLE|ALL_RESULTS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
1105 nis_freeresult(result);
1107 if(delresult->status != NIS_SUCCESS) {
1108 DEBUG(0, ("NIS+ table update failed: %s %s\n",
1109 nisname, nis_sperrno(delresult->status)));
1110 nis_freeresult(delresult);
1113 nis_freeresult(delresult);
1117 /************************************************************************
1118 Routine to add an entry to the nisplus passwd file.
1119 *************************************************************************/
1120 BOOL pdb_add_sam_account(const SAM_ACCOUNT * newpwd)
1126 nis_result *result = NULL,
1133 * 1. find user domain.
1134 * a. try nis search in passwd.org_dir - if found use domain from result.
1135 * b. try getpwnam. this may be needed if user is defined
1136 * in /etc/passwd file (or elsewere) and not in passwd.org_dir.
1137 * if found, use host default domain.
1138 * c. exit with False - no such user.
1141 * a. find smbpasswd table
1142 * search pfile in user domain if not found, try host default
1144 * b. smbpasswd domain is found, fill data and add entry.
1146 * pfile should contain ONLY table name, org_dir will be concated.
1147 * so, at first we will clear path prefix from pfile, and
1148 * then we will use pfiletmp as playground to put together full
1150 * such approach will make it possible to specify samba private dir
1151 * AND still use NIS+ table. as all domain related data is normally
1152 * stored in org_dir.DOMAIN, this should be ok do do.
1155 pfile = lp_smb_passwd_file();
1156 if( strrchr( pfile, '/') )
1157 pfile = strrchr( pfile, '/') + 1;
1160 * Check if user is already there.
1162 safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
1163 safe_strcat(pfiletmp, ".org_dir",
1164 sizeof(pfiletmp)-strlen(pfiletmp)-1);
1166 if(pdb_get_username(newpwd) != NULL) {
1167 nisname = make_nisname_from_name(pdb_get_username(newpwd),
1173 if(!(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
1174 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
1177 if (result->status != NIS_SUCCESS &&
1178 result->status != NIS_NOTFOUND) {
1179 DEBUG(3, ( "nis_list failure: %s: %s\n",
1180 nisname, nis_sperrno(result->status)));
1181 nis_freeresult(result);
1185 if (result->status == NIS_SUCCESS && NIS_RES_NUMOBJ(result) > 0)
1187 DEBUG(3, ("User already exists in NIS+ password db: %s\n",
1189 nis_freeresult(result);
1193 nis_freeresult(result); /* no such user, free results */
1196 * check for user in unix password database. we need this to get
1197 * domain, where smbpasswd entry should be stored.
1200 nisname = make_nisname_from_name(pdb_get_username(newpwd),
1203 result = nisp_get_nis_list(nisname,
1204 MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
1205 EXPAND_NAME|HARD_LOOKUP);
1207 if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0)
1209 DEBUG(3, ("nis_list failure: %s: %s\n",
1210 nisname, nis_sperrno(result->status)));
1211 nis_freeresult(result);
1213 if (!sys_getpwnam(pdb_get_username(newpwd))) {
1214 /* no such user in system! */
1218 * user is defined, but not in passwd.org_dir.
1222 safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
1223 safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1);
1224 safe_strcat(pfiletmp, NIS_RES_OBJECT(result)->zo_domain,
1225 sizeof(pfiletmp)-strlen(pfiletmp)-1);
1226 nis_freeresult(result); /* not needed any more */
1228 tblresult = nisp_get_nis_list(pfiletmp,
1229 MASTER_ONLY|FOLLOW_LINKS|\
1230 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
1233 if (local_user || tblresult->status != NIS_SUCCESS)
1237 * smbpasswd table not found in user domain, fallback to
1240 if (!local_user) /* free previous failed search result */
1241 nis_freeresult(tblresult);
1243 safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
1244 safe_strcat(pfiletmp, ".org_dir",
1245 sizeof(pfiletmp)-strlen(pfiletmp)-1);
1246 tblresult = nis_lookup(pfiletmp, MASTER_ONLY|FOLLOW_LINKS|\
1247 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
1248 if (tblresult->status != NIS_SUCCESS)
1250 /* still nothing. bail out */
1251 nis_freeresult(tblresult);
1252 DEBUG(3, ( "nis_lookup failure: %s\n",
1253 nis_sperrno(tblresult->status)));
1256 /* we need full name for nis_add_entry() */
1257 safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
1258 safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1);
1259 safe_strcat(pfiletmp, NIS_RES_OBJECT(tblresult)->zo_domain,
1260 sizeof(pfiletmp)-strlen(pfiletmp)-1);
1263 memset((char *)&new_obj, 0, sizeof (new_obj));
1264 /* fill entry headers */
1265 /* we do not free these. */
1266 new_obj.zo_name = NIS_RES_OBJECT(tblresult)->zo_name;
1267 new_obj.zo_owner = NIS_RES_OBJECT(tblresult)->zo_owner;
1268 new_obj.zo_group = NIS_RES_OBJECT(tblresult)->zo_group;
1269 new_obj.zo_domain = NIS_RES_OBJECT(tblresult)->zo_domain;
1271 new_obj.zo_access = NIS_RES_OBJECT(tblresult)->zo_access;
1272 new_obj.zo_ttl = NIS_RES_OBJECT(tblresult)->zo_ttl;
1274 new_obj.zo_data.zo_type = ENTRY_OBJ;
1275 new_obj.EN_data.en_type =
1276 NIS_RES_OBJECT(tblresult)->TA_data.ta_type;
1278 ta_maxcol = NIS_RES_OBJECT(tblresult)->TA_data.ta_maxcol;
1280 if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
1281 DEBUG(0, ("memory allocation failure\n"));
1282 nis_freeresult(tblresult);
1286 memset((char *)ecol, 0, ta_maxcol*sizeof (entry_col));
1287 new_obj.EN_data.en_cols.en_cols_val = ecol;
1288 new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
1290 init_nisp_from_sam(&new_obj, newpwd, NULL);
1292 DEBUG(10, ( "add NIS+ entry: %s\n", nisname));
1293 result = nis_add_entry(pfiletmp, &new_obj, 0);
1295 free(ecol); /* free allocated entry space */
1297 if (result->status != NIS_SUCCESS)
1299 DEBUG(3, ( "NIS+ table update failed: %s\n",
1300 nisname, nis_sperrno(result->status)));
1301 nis_freeresult(tblresult);
1302 nis_freeresult(result);
1306 nis_freeresult(tblresult);
1307 nis_freeresult(result);
1312 /************************************************************************
1313 Routine to modify the nisplus passwd entry.
1314 ************************************************************************/
1315 BOOL pdb_update_sam_account(const SAM_ACCOUNT * newpwd, BOOL override)
1317 nis_result *result, *addresult;
1322 char *pfile = lp_smb_passwd_file();
1328 DEBUG(0, ("no SMB password file set\n"));
1331 if( strrchr( pfile, '/') )
1332 pfile = strrchr( pfile, '/') + 1;
1334 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir",
1335 pdb_get_username(newpwd), pfile);
1337 DEBUG(10, ("search by name: %s\n", nisname));
1339 /* Search the table. */
1341 if( !(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
1342 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
1346 if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
1347 /* User not found. */
1348 DEBUG(0,("user not found in NIS+\n"));
1349 nis_freeresult(result);
1353 obj = NIS_RES_OBJECT(result);
1354 DEBUG(6,("entry found in %s\n", obj->zo_domain));
1356 /* we must create new stub object with EN_MODIFIED flag.
1357 this is because obj from result is going to be freed and
1358 we do not want to break it or cause memory leaks or corruption.
1361 memmove((char *)&new_obj, obj, sizeof (new_obj));
1362 ta_maxcol = obj->TA_data.ta_maxcol;
1364 if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
1365 DEBUG(0, ("memory allocation failure\n"));
1366 nis_freeresult(result);
1370 memmove((char *)ecol, obj->EN_data.en_cols.en_cols_val,
1371 ta_maxcol*sizeof (entry_col));
1372 new_obj.EN_data.en_cols.en_cols_val = ecol;
1373 new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
1375 if ( init_nisp_from_sam(&new_obj, newpwd, obj) == True ) {
1376 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s",
1377 pdb_get_username(newpwd), pfile, obj->zo_domain);
1379 DEBUG(10, ("NIS+ table update: %s\n", nisname));
1381 nis_modify_entry(nisname, &new_obj,
1382 MOD_SAMEOBJ | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP);
1384 if(addresult->status != NIS_SUCCESS) {
1385 DEBUG(0, ("NIS+ table update failed: %s %s\n",
1386 nisname, nis_sperrno(addresult->status)));
1387 nis_freeresult(addresult);
1388 nis_freeresult(result);
1393 DEBUG(6,("password changed\n"));
1394 nis_freeresult(addresult);
1396 DEBUG(6,("nothing to change!\n"));
1400 nis_freeresult(result);
1406 void nisplus_dummy_function(void);
1407 void nisplus_dummy_function(void) { } /* stop some compilers complaining */
1408 #endif /* WITH_NISPLUSSAM */