if we are adding a new sambaAccount, make sure that we add a
[Samba.git] / source / passdb / pdb_nisplus.c
blob0bcae57c2b48e93d5c0c16a99ba962e6b73629e5
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 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_name
140 ****************************************************************/
141 static char *make_nisname_from_name(char *user_name, char *pfile)
143 static pstring nisname;
145 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", user_name, pfile);
147 return nisname;
150 /***************************************************************
151 smb_passwd_table
153 * if only plain table in is in pfile, org_dir will be concated.
154 * so, at first we will clear path prefix from pfile, and
155 * then we will use pfiletmp as playground to put together full
156 * nisname string.
157 * such approach will make it possible to specify samba private dir
158 * AND still use NIS+ table. as all domain related data is normally
159 * stored in org_dir.DOMAIN, this should be ok to do.
160 ****************************************************************/
161 static char *smb_passwd_table(){
162 char *sp, *p = lp_smb_passwd_file();
163 #if 1
164 static pstring pfiletmp;
165 #endif
167 /* if lp_smb_passwd_file() returns anything wierd, pass it on */
168 if (!p || !*p) return p;
169 sp = strrchr( p, '/' );
170 if (sp) p=sp+1;
172 #if 1
173 /* append org_dir ONLY if plain table name is used.
174 why we do append it is because NIS_PATH env may not be set,
175 should we check if it's set?
176 do not append if lp_smb_passwd_file() returns an empty string
178 if (!strchr(p, '.')){
179 slprintf(pfiletmp, sizeof(pfiletmp)-1, "%s.org_dir", p);
180 return pfiletmp;
182 #endif
183 return p;
187 /*************************************************************************
188 gets a NIS+ attribute
189 *************************************************************************/
190 static void get_single_attribute(nis_object *new_obj, int col,
191 char *val, int len)
193 int entry_len;
195 if (new_obj == NULL || val == NULL) return;
197 entry_len = ENTRY_LEN(new_obj, col);
198 if (len > entry_len)
200 len = entry_len;
203 safe_strcpy(val, ENTRY_VAL(new_obj, col), len-1);
206 /************************************************************************
207 makes a struct sam_passwd from a NIS+ object.
208 ************************************************************************/
209 static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, nis_object *obj)
211 char *ptr;
212 pstring full_name; /* this must be translated to dos code page */
213 pstring acct_desc; /* this must be translated to dos code page */
214 pstring home_dir; /* set default value from smb.conf for user */
215 pstring home_drive; /* set default value from smb.conf for user */
216 pstring logon_script; /* set default value from smb.conf for user */
217 pstring profile_path; /* set default value from smb.conf for user */
218 pstring hours;
219 int hours_len;
220 unsigned char smbpwd[16];
221 unsigned char smbntpwd[16];
225 * time values. note: this code assumes 32bit time_t!
228 pdb_set_logon_time(pw_buf, (time_t)0);
229 ptr = ENTRY_VAL(obj, NPF_LOGON_T);
230 if(ptr && *ptr && (StrnCaseCmp(ptr, "LNT-", 4)==0)) {
231 int i;
232 ptr += 4;
233 for(i = 0; i < 8; i++) {
234 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
235 break;
237 if(i == 8) {
238 pdb_set_logon_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
242 pdb_set_logoff_time(pw_buf, get_time_t_max());
243 ptr = ENTRY_VAL(obj, NPF_LOGOFF_T);
244 if(ptr && *ptr && (StrnCaseCmp(ptr, "LOT-", 4)==0)) {
245 int i;
246 ptr += 4;
247 for(i = 0; i < 8; i++) {
248 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
249 break;
251 if(i == 8) {
252 pdb_set_logoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
256 pdb_set_kickoff_time(pw_buf, get_time_t_max());
257 ptr = ENTRY_VAL(obj, NPF_KICK_T);
258 if(ptr && *ptr && (StrnCaseCmp(ptr, "KOT-", 4)==0)) {
259 int i;
260 ptr += 4;
261 for(i = 0; i < 8; i++) {
262 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
263 break;
265 if(i == 8) {
266 pdb_set_kickoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
270 pdb_set_pass_last_set_time(pw_buf, (time_t)0);
271 ptr = ENTRY_VAL(obj, NPF_PWDLSET_T);
272 if(ptr && *ptr && (StrnCaseCmp(ptr, "LCT-", 4)==0)) {
273 int i;
274 ptr += 4;
275 for(i = 0; i < 8; i++) {
276 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
277 break;
279 if(i == 8) {
280 pdb_set_pass_last_set_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
284 pdb_set_pass_can_change_time(pw_buf, (time_t)0);
285 ptr = ENTRY_VAL(obj, NPF_PWDCCHG_T);
286 if(ptr && *ptr && (StrnCaseCmp(ptr, "CCT-", 4)==0)) {
287 int i;
288 ptr += 4;
289 for(i = 0; i < 8; i++) {
290 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
291 break;
293 if(i == 8) {
294 pdb_set_pass_can_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
298 pdb_set_pass_must_change_time(pw_buf, get_time_t_max()); /* Password never expires. */
299 ptr = ENTRY_VAL(obj, NPF_PWDMCHG_T);
300 if(ptr && *ptr && (StrnCaseCmp(ptr, "MCT-", 4)==0)) {
301 int i;
302 ptr += 4;
303 for(i = 0; i < 8; i++) {
304 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
305 break;
307 if(i == 8) {
308 pdb_set_pass_must_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
312 /* string values */
313 pdb_set_username(pw_buf, ENTRY_VAL(obj, NPF_NAME));
314 pdb_set_domain(pw_buf, lp_workgroup());
315 /* pdb_set_nt_username() -- cant set it here... */
317 get_single_attribute(obj, NPF_FULL_NAME, full_name, sizeof(pstring));
318 unix_to_dos(full_name);
319 pdb_set_fullname(pw_buf, full_name);
321 pdb_set_acct_ctrl(pw_buf, pdb_decode_acct_ctrl(ENTRY_VAL(obj,
322 NPF_ACB)));
324 get_single_attribute(obj, NPF_ACCT_DESC, acct_desc, sizeof(pstring));
325 unix_to_dos(acct_desc);
326 pdb_set_acct_desc(pw_buf, acct_desc);
328 pdb_set_workstations(pw_buf, ENTRY_VAL(obj, NPF_WORKSTATIONS));
329 pdb_set_munged_dial(pw_buf, NULL);
331 /* Might want to consult sys_getpwnam for the following two.
332 for now, use same default as pdb_fill-default_sam */
334 ptr = ENTRY_VAL(obj, NPF_UID);
335 pdb_set_uid(pw_buf, ptr ? atoi(ptr) : -1);
337 ptr = ENTRY_VAL(obj, NPF_SMB_GRPID);
338 pdb_set_gid(pw_buf, ptr ? atoi(ptr) : -1);
341 ptr = ENTRY_VAL(obj, NPF_USER_RID);
342 pdb_set_user_rid(pw_buf, ptr ? atoi(ptr) :
343 pdb_uid_to_user_rid(pdb_get_uid(pw_buf)));
345 ptr = ENTRY_VAL(obj, NPF_GROUP_RID);
346 pdb_set_group_rid(pw_buf, ptr ? atoi(ptr) :
347 pdb_gid_to_group_rid(pdb_get_gid(pw_buf)));
350 /* values, must exist for user */
351 if( !(pdb_get_acct_ctrl(pw_buf) & ACB_WSTRUST) ) {
352 /* FIXME!! This doesn't belong here.
353 Should be set in net_sam_logon()
354 --jerry */
355 pstrcpy(samlogon_user, pdb_get_username(pw_buf));
357 get_single_attribute(obj, NPF_HOME_DIR, home_dir, sizeof(pstring));
358 if( !(home_dir && *home_dir) ) {
359 pstrcpy(home_dir, lp_logon_home());
360 pdb_set_homedir(pw_buf, home_dir, False);
362 else
363 pdb_set_homedir(pw_buf, home_dir, True);
365 get_single_attribute(obj, NPF_DIR_DRIVE, home_drive, sizeof(pstring));
366 if( !(home_drive && *home_drive) ) {
367 pstrcpy(home_drive, lp_logon_drive());
368 pdb_set_dir_drive(pw_buf, home_drive, False);
370 else
371 pdb_set_dir_drive(pw_buf, home_drive, True);
373 get_single_attribute(obj, NPF_LOGON_SCRIPT, logon_script,
374 sizeof(pstring));
375 if( !(logon_script && *logon_script) ) {
376 pstrcpy(logon_script, lp_logon_script());
377 pdb_set_logon_script(pw_buf, logon_script, False);
379 else
380 pdb_set_logon_script(pw_buf, logon_script, True);
382 get_single_attribute(obj, NPF_PROFILE_PATH, profile_path, sizeof(pstring));
383 if( !(profile_path && *profile_path) ) {
384 pstrcpy(profile_path, lp_logon_path());
385 pdb_set_profile_path(pw_buf, profile_path, False);
387 else
388 pdb_set_profile_path(pw_buf, profile_path, True);
391 else
393 /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
394 pdb_set_group_rid (pw_buf, DOMAIN_GROUP_RID_USERS);
397 /* Check the lanman password column. */
398 ptr = ENTRY_VAL(obj, NPF_LMPWD);
399 if (!pdb_set_lanman_passwd(pw_buf, NULL))
400 return False;
402 if (!strncasecmp(ptr, "NO PASSWORD", 11)) {
403 pdb_set_acct_ctrl(pw_buf, pdb_get_acct_ctrl(pw_buf) | ACB_PWNOTREQ);
404 } else {
405 if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbpwd)) {
406 DEBUG(0, ("malformed LM pwd entry: %s.\n",
407 pdb_get_username(pw_buf)));
408 return False;
410 if (!pdb_set_lanman_passwd(pw_buf, smbpwd))
411 return False;
414 /* Check the NT password column. */
415 ptr = ENTRY_VAL(obj, NPF_NTPWD);
416 if (!pdb_set_nt_passwd(pw_buf, NULL))
417 return False;
419 if (!(pdb_get_acct_ctrl(pw_buf) & ACB_PWNOTREQ) &&
420 strncasecmp(ptr, "NO PASSWORD", 11)) {
421 if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbntpwd)) {
422 DEBUG(0, ("malformed NT pwd entry:\
423 uid = %d.\n",
424 pdb_get_uid(pw_buf)));
425 return False;
427 if (!pdb_set_nt_passwd(pw_buf, smbntpwd))
428 return False;
431 pdb_set_unknown_3(pw_buf, 0xffffff); /* don't know */
432 pdb_set_logon_divs(pw_buf, 168); /* hours per week */
434 if( (hours_len = ENTRY_LEN(obj, NPF_HOURS)) == 21 ) {
435 memcpy(hours, ENTRY_VAL(obj, NPF_HOURS), hours_len);
436 } else {
437 hours_len = 21; /* 21 times 8 bits = 168 */
438 /* available at all hours */
439 memset(hours, 0xff, hours_len);
441 pdb_set_hours_len(pw_buf, hours_len);
442 pdb_set_hours(pw_buf, (uchar *)hours);
444 pdb_set_unknown_5(pw_buf, 0x00020000); /* don't know */
445 pdb_set_unknown_6(pw_buf, 0x000004ec); /* don't know */
447 return True;
450 /************************************************************************
451 makes a struct sam_passwd from a NIS+ result.
452 ************************************************************************/
453 static BOOL make_sam_from_nisresult(SAM_ACCOUNT *pw_buf, nis_result *result)
455 if (pw_buf == NULL || result == NULL) return False;
457 if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND)
459 DEBUG(0, ("NIS+ lookup failure: %s\n",
460 nis_sperrno(result->status)));
461 return False;
464 /* User not found. */
465 if (NIS_RES_NUMOBJ(result) <= 0)
467 DEBUG(10, ("user not found in NIS+\n"));
468 return False;
471 if (NIS_RES_NUMOBJ(result) > 1)
473 DEBUG(10, ("WARNING: Multiple entries for user in NIS+ table!\n"));
476 /* Grab the first hit. */
477 return make_sam_from_nisp_object(pw_buf, &NIS_RES_OBJECT(result)[0]);
480 /*************************************************************************
481 sets a NIS+ attribute
482 *************************************************************************/
483 static void set_single_attribute(nis_object *new_obj, int col,
484 char *val, int len, int flags)
486 if (new_obj == NULL) return;
488 ENTRY_VAL(new_obj, col) = val;
489 ENTRY_LEN(new_obj, col) = len+1;
491 if (flags != 0)
493 new_obj->EN_data.en_cols.en_cols_val[col].ec_flags = flags;
497 /***************************************************************
498 copy or modify nis object. this object is used to add or update
499 nisplus table entry.
500 ****************************************************************/
501 static BOOL init_nisp_from_sam(nis_object *obj, SAM_ACCOUNT *sampass,
502 nis_object *old)
505 * Fill nis_object for entry add or update.
506 * if we are updateing, we have to find out differences and set
507 * EN_MODIFIED flag. also set need_to_modify to trigger
508 * nis_modify_entry() call in pdb_update_sam_account().
510 * TODO:
511 * get data from SAM
512 * if (modify) get data from nis_object, compare and store if
513 * different + set EN_MODIFIED and need_to_modify
514 * else
515 * store
517 BOOL need_to_modify = False;
518 char *name; /* from SAM */
519 /* these must be static or allocate and free entry columns! */
520 static fstring uid; /* from SAM */
521 static fstring user_rid; /* from SAM */
522 static fstring gid; /* from SAM */
523 static fstring group_rid; /* from SAM */
524 char *acb; /* from SAM */
525 static fstring smb_passwd; /* from SAM */
526 static fstring smb_nt_passwd; /* from SAM */
527 static fstring logon_t; /* from SAM */
528 static fstring logoff_t; /* from SAM */
529 static fstring kickoff_t; /* from SAM */
530 static fstring pwdlset_t; /* from SAM */
531 static fstring pwdlchg_t; /* from SAM */
532 static fstring pwdmchg_t; /* from SAM */
533 static fstring full_name; /* from SAM */
534 static fstring acct_desc; /* from SAM */
535 static char empty[1]; /* just an empty string */
538 name = pdb_get_username(sampass);
539 slprintf(uid, sizeof(uid)-1, "%u", pdb_get_uid(sampass));
540 slprintf(user_rid, sizeof(user_rid)-1, "%u",
541 pdb_get_user_rid(sampass)? pdb_get_user_rid(sampass):
542 pdb_uid_to_user_rid(pdb_get_uid(sampass)));
543 slprintf(gid, sizeof(gid)-1, "%u", pdb_get_gid(sampass));
544 slprintf(group_rid, sizeof(group_rid)-1, "%u",
545 pdb_get_group_rid(sampass)? pdb_get_group_rid(sampass):
546 pdb_gid_to_group_rid(pdb_get_gid(sampass)));
547 acb = pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sampass),
548 NEW_PW_FORMAT_SPACE_PADDED_LEN);
549 pdb_sethexpwd (smb_passwd, pdb_get_lanman_passwd(sampass),
550 pdb_get_acct_ctrl(sampass));
551 pdb_sethexpwd (smb_nt_passwd, pdb_get_nt_passwd(sampass),
552 pdb_get_acct_ctrl(sampass));
553 slprintf(logon_t, 13, "LNT-%08X",
554 (uint32)pdb_get_logon_time(sampass));
555 slprintf(logoff_t, 13, "LOT-%08X",
556 (uint32)pdb_get_logoff_time(sampass));
557 slprintf(kickoff_t, 13, "KOT-%08X",
558 (uint32)pdb_get_kickoff_time(sampass));
559 slprintf(pwdlset_t, 13, "LCT-%08X",
560 (uint32)pdb_get_pass_last_set_time(sampass));
561 slprintf(pwdlchg_t, 13, "CCT-%08X",
562 (uint32)pdb_get_pass_can_change_time(sampass));
563 slprintf(pwdmchg_t, 13, "MCT-%08X",
564 (uint32)pdb_get_pass_must_change_time(sampass));
565 safe_strcpy(full_name, pdb_get_fullname(sampass), sizeof(full_name)-1);
566 dos_to_unix(full_name);
567 safe_strcpy(acct_desc, pdb_get_acct_desc(sampass), sizeof(acct_desc)-1);
568 dos_to_unix(acct_desc);
570 if( old ) {
571 /* name */
572 if(strcmp(ENTRY_VAL(old, NPF_NAME), name))
574 need_to_modify = True;
575 set_single_attribute(obj, NPF_NAME, name, strlen(name),
576 EN_MODIFIED);
580 /* uid */
581 if(pdb_get_uid(sampass) != -1) {
582 if(!ENTRY_VAL(old, NPF_UID) || strcmp(ENTRY_VAL(old, NPF_UID), uid))
584 need_to_modify = True;
585 set_single_attribute(obj, NPF_UID, uid,
586 strlen(uid), EN_MODIFIED);
590 /* user_rid */
591 if (pdb_get_user_rid(sampass)) {
592 if(!ENTRY_VAL(old, NPF_USER_RID) ||
593 strcmp(ENTRY_VAL(old, NPF_USER_RID), user_rid) ) {
594 need_to_modify = True;
595 set_single_attribute(obj, NPF_USER_RID, user_rid,
596 strlen(user_rid), EN_MODIFIED);
600 /* smb_grpid */
601 if (pdb_get_gid(sampass) != -1) {
602 if(!ENTRY_VAL(old, NPF_SMB_GRPID) ||
603 strcmp(ENTRY_VAL(old, NPF_SMB_GRPID), gid) ) {
604 need_to_modify = True;
605 set_single_attribute(obj, NPF_SMB_GRPID, gid,
606 strlen(gid), EN_MODIFIED);
610 /* group_rid */
611 if (pdb_get_group_rid(sampass)) {
612 if(!ENTRY_VAL(old, NPF_GROUP_RID) ||
613 strcmp(ENTRY_VAL(old, NPF_GROUP_RID), group_rid) ) {
614 need_to_modify = True;
615 set_single_attribute(obj, NPF_GROUP_RID, group_rid,
616 strlen(group_rid), EN_MODIFIED);
620 /* acb */
621 if (!ENTRY_VAL(old, NPF_ACB) ||
622 strcmp(ENTRY_VAL(old, NPF_ACB), acb)) {
623 need_to_modify = True;
624 set_single_attribute(obj, NPF_ACB, acb, strlen(acb), EN_MODIFIED);
627 /* lmpwd */
628 if(!ENTRY_VAL(old, NPF_LMPWD) ||
629 strcmp(ENTRY_VAL(old, NPF_LMPWD), smb_passwd) ) {
630 need_to_modify = True;
631 set_single_attribute(obj, NPF_LMPWD, smb_passwd,
632 strlen(smb_passwd), EN_CRYPT|EN_MODIFIED);
635 /* ntpwd */
636 if(!ENTRY_VAL(old, NPF_NTPWD) ||
637 strcmp(ENTRY_VAL(old, NPF_NTPWD), smb_nt_passwd) ) {
638 need_to_modify = True;
639 set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd,
640 strlen(smb_nt_passwd), EN_CRYPT|EN_MODIFIED);
643 /* logon_t */
644 if( pdb_get_logon_time(sampass) &&
645 (!ENTRY_VAL(old, NPF_LOGON_T) ||
646 strcmp(ENTRY_VAL(old, NPF_LOGON_T), logon_t ))) {
647 need_to_modify = True;
648 set_single_attribute(obj, NPF_LOGON_T, logon_t,
649 strlen(logon_t), EN_MODIFIED);
652 /* logoff_t */
653 if( pdb_get_logoff_time(sampass) &&
654 (!ENTRY_VAL(old, NPF_LOGOFF_T) ||
655 strcmp(ENTRY_VAL(old, NPF_LOGOFF_T), logoff_t))) {
656 need_to_modify = True;
657 set_single_attribute(obj, NPF_LOGOFF_T, logoff_t,
658 strlen(logoff_t), EN_MODIFIED);
661 /* kick_t */
662 if( pdb_get_kickoff_time(sampass) &&
663 (!ENTRY_VAL(old, NPF_KICK_T) ||
664 strcmp(ENTRY_VAL(old, NPF_KICK_T), kickoff_t))) {
665 need_to_modify = True;
666 set_single_attribute(obj, NPF_KICK_T, kickoff_t,
667 strlen(kickoff_t), EN_MODIFIED);
670 /* pwdlset_t */
671 if( pdb_get_pass_last_set_time(sampass) &&
672 (!ENTRY_VAL(old, NPF_PWDLSET_T) ||
673 strcmp(ENTRY_VAL(old, NPF_PWDLSET_T), pwdlset_t))) {
674 need_to_modify = True;
675 set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t,
676 strlen(pwdlset_t), EN_MODIFIED);
679 /* pwdlchg_t */
680 if( pdb_get_pass_can_change_time(sampass) &&
681 (!ENTRY_VAL(old, NPF_PWDCCHG_T) ||
682 strcmp(ENTRY_VAL(old, NPF_PWDCCHG_T), pwdlchg_t))) {
683 need_to_modify = True;
684 set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t,
685 strlen(pwdlchg_t), EN_MODIFIED);
688 /* pwdmchg_t */
689 if( pdb_get_pass_must_change_time(sampass) &&
690 (!ENTRY_VAL(old, NPF_PWDMCHG_T) ||
691 strcmp(ENTRY_VAL(old, NPF_PWDMCHG_T), pwdmchg_t))) {
692 need_to_modify = True;
693 set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t,
694 strlen(pwdmchg_t), EN_MODIFIED);
697 /* full_name */
698 /* must support set, unset and change */
699 if ( (pdb_get_fullname(sampass) &&
700 !ENTRY_VAL(old, NPF_FULL_NAME)) ||
701 (ENTRY_VAL(old, NPF_FULL_NAME) &&
702 !pdb_get_fullname(sampass)) ||
703 (ENTRY_VAL(old, NPF_FULL_NAME) &&
704 pdb_get_fullname(sampass) &&
705 strcmp( ENTRY_VAL(old, NPF_FULL_NAME), full_name ))) {
706 need_to_modify = True;
707 set_single_attribute(obj, NPF_FULL_NAME, full_name,
708 strlen(full_name), EN_MODIFIED);
711 /* home_dir */
712 /* must support set, unset and change */
713 if( (pdb_get_homedir(sampass) &&
714 !ENTRY_VAL(old, NPF_HOME_DIR)) ||
715 (ENTRY_VAL(old, NPF_HOME_DIR) &&
716 !pdb_get_homedir(sampass)) ||
717 (ENTRY_VAL(old, NPF_HOME_DIR) &&
718 pdb_get_homedir(sampass) &&
719 strcmp( ENTRY_VAL(old, NPF_HOME_DIR),
720 pdb_get_homedir(sampass)))) {
721 need_to_modify = True;
722 set_single_attribute(obj, NPF_HOME_DIR, pdb_get_homedir(sampass),
723 strlen(pdb_get_homedir(sampass)), EN_MODIFIED);
726 /* dir_drive */
727 /* must support set, unset and change */
728 if( (pdb_get_dirdrive(sampass) &&
729 !ENTRY_VAL(old, NPF_DIR_DRIVE)) ||
730 (ENTRY_VAL(old, NPF_DIR_DRIVE) &&
731 !pdb_get_dirdrive(sampass)) ||
732 (ENTRY_VAL(old, NPF_DIR_DRIVE) &&
733 pdb_get_dirdrive(sampass) &&
734 strcmp( ENTRY_VAL(old, NPF_DIR_DRIVE),
735 pdb_get_dirdrive(sampass)))) {
736 need_to_modify = True;
737 set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dirdrive(sampass),
738 strlen(pdb_get_dirdrive(sampass)), EN_MODIFIED);
741 /* logon_script */
742 /* must support set, unset and change */
743 if( (pdb_get_logon_script(sampass) &&
744 !ENTRY_VAL(old, NPF_LOGON_SCRIPT) ||
745 (ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
746 !pdb_get_logon_script(sampass)) ||
747 ( ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
748 pdb_get_logon_script(sampass) &&
749 strcmp( ENTRY_VAL(old, NPF_LOGON_SCRIPT),
750 pdb_get_logon_script(sampass))))) {
751 need_to_modify = True;
752 set_single_attribute(obj, NPF_LOGON_SCRIPT,
753 pdb_get_logon_script(sampass),
754 strlen(pdb_get_logon_script(sampass)),
755 EN_MODIFIED);
758 /* profile_path */
759 /* must support set, unset and change */
760 if( (pdb_get_profile_path(sampass) &&
761 !ENTRY_VAL(old, NPF_PROFILE_PATH)) ||
762 (ENTRY_VAL(old, NPF_PROFILE_PATH) &&
763 !pdb_get_profile_path(sampass)) ||
764 (ENTRY_VAL(old, NPF_PROFILE_PATH) &&
765 pdb_get_profile_path(sampass) &&
766 strcmp( ENTRY_VAL(old, NPF_PROFILE_PATH),
767 pdb_get_profile_path(sampass) ) )) {
768 need_to_modify = True;
769 set_single_attribute(obj, NPF_PROFILE_PATH,
770 pdb_get_profile_path(sampass),
771 strlen(pdb_get_profile_path(sampass)),
772 EN_MODIFIED);
775 /* acct_desc */
776 /* must support set, unset and change */
777 if( (pdb_get_acct_desc(sampass) &&
778 !ENTRY_VAL(old, NPF_ACCT_DESC)) ||
779 (ENTRY_VAL(old, NPF_ACCT_DESC) &&
780 !pdb_get_acct_desc(sampass)) ||
781 (ENTRY_VAL(old, NPF_ACCT_DESC) &&
782 pdb_get_acct_desc(sampass) &&
783 strcmp( ENTRY_VAL(old, NPF_ACCT_DESC), acct_desc ) )) {
784 need_to_modify = True;
785 set_single_attribute(obj, NPF_ACCT_DESC, acct_desc,
786 strlen(acct_desc), EN_MODIFIED);
789 /* workstations */
790 /* must support set, unset and change */
791 if ( (pdb_get_workstations(sampass) &&
792 !ENTRY_VAL(old, NPF_WORKSTATIONS) ) ||
793 (ENTRY_VAL(old, NPF_WORKSTATIONS) &&
794 !pdb_get_workstations(sampass)) ||
795 (ENTRY_VAL(old, NPF_WORKSTATIONS) &&
796 pdb_get_workstations(sampass)) &&
797 strcmp( ENTRY_VAL(old, NPF_WORKSTATIONS),
798 pdb_get_workstations(sampass))) {
799 need_to_modify = True;
800 set_single_attribute(obj, NPF_WORKSTATIONS,
801 pdb_get_workstations(sampass),
802 strlen(pdb_get_workstations(sampass)),
803 EN_MODIFIED);
806 /* hours */
807 if ((pdb_get_hours_len(sampass) != ENTRY_LEN(old, NPF_HOURS)) ||
808 memcmp(pdb_get_hours(sampass), ENTRY_VAL(old, NPF_HOURS),
809 ENTRY_LEN(old, NPF_HOURS))) {
810 need_to_modify = True;
811 /* set_single_attribute will add 1 for len ... */
812 set_single_attribute(obj, NPF_HOURS, (char *)pdb_get_hours(sampass),
813 pdb_get_hours_len(sampass)-1, EN_MODIFIED);
815 } else {
816 char *homedir, *dirdrive, *logon_script, *profile_path, *workstations;
818 *empty = '\0'; /* empty string */
820 set_single_attribute(obj, NPF_NAME, name, strlen(name), 0);
821 set_single_attribute(obj, NPF_UID, uid, strlen(uid), 0);
822 set_single_attribute(obj, NPF_USER_RID, user_rid,
823 strlen(user_rid), 0);
824 set_single_attribute(obj, NPF_SMB_GRPID, gid, strlen(gid), 0);
825 set_single_attribute(obj, NPF_GROUP_RID, group_rid,
826 strlen(group_rid), 0);
827 set_single_attribute(obj, NPF_ACB, acb, strlen(acb), 0);
828 set_single_attribute(obj, NPF_LMPWD, smb_passwd,
829 strlen(smb_passwd), EN_CRYPT);
830 set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd,
831 strlen(smb_nt_passwd), EN_CRYPT);
832 set_single_attribute(obj, NPF_LOGON_T, logon_t,
833 strlen(logon_t), 0);
834 set_single_attribute(obj, NPF_LOGOFF_T, logoff_t,
835 strlen(logoff_t), 0);
836 set_single_attribute(obj, NPF_KICK_T, kickoff_t,
837 strlen(kickoff_t),0);
838 set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t,
839 strlen(pwdlset_t), 0);
840 set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t,
841 strlen(pwdlchg_t), 0);
842 set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t,
843 strlen(pwdmchg_t), 0);
844 set_single_attribute(obj, NPF_FULL_NAME ,
845 full_name, strlen(full_name), 0);
847 if(!(homedir = pdb_get_homedir(sampass)))
848 homedir = empty;
850 set_single_attribute(obj, NPF_HOME_DIR,
851 homedir, strlen(homedir), 0);
853 if(!(dirdrive = pdb_get_dirdrive(sampass)))
854 dirdrive = empty;
856 set_single_attribute(obj, NPF_DIR_DRIVE,
857 dirdrive, strlen(dirdrive), 0);
859 if(!(logon_script = pdb_get_logon_script(sampass)))
860 logon_script = empty;
862 set_single_attribute(obj, NPF_LOGON_SCRIPT,
863 logon_script, strlen(logon_script), 0);
865 if(!(profile_path = pdb_get_profile_path(sampass)))
866 profile_path = empty;
868 set_single_attribute(obj, NPF_PROFILE_PATH,
869 profile_path, strlen(profile_path), 0);
871 set_single_attribute(obj, NPF_ACCT_DESC,
872 acct_desc, strlen(acct_desc), 0);
874 if(!(workstations = pdb_get_workstations(sampass)))
875 workstations = empty;
877 set_single_attribute(obj, NPF_WORKSTATIONS,
878 workstations, strlen(workstations), 0);
880 /* set_single_attribute will add 1 for len ... */
881 set_single_attribute(obj, NPF_HOURS,
882 (char *)pdb_get_hours(sampass),
883 pdb_get_hours_len(sampass)-1, 0);
886 return need_to_modify;
889 /***************************************************************
890 calls nis_list, returns results.
891 ****************************************************************/
892 static nis_result *nisp_get_nis_list(char *nis_name, unsigned int flags)
894 nis_result *result;
895 int i;
897 if( ! flags)
898 flags = FOLLOW_LINKS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP;
900 for(i = 0; i<2;i++ ) {
901 alarm(60); /* hopefully ok for long searches */
902 result = nis_list(nis_name, flags,NULL,NULL);
904 alarm(0);
905 CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
907 if (gotalarm)
909 DEBUG(0,("NIS+ lookup time out\n"));
910 nis_freeresult(result);
911 return NULL;
913 if( !(flags & MASTER_ONLY) && NIS_RES_NUMOBJ(result) <= 0 ) {
914 /* nis replicas are not in sync perhaps?
915 * this can happen, if account was just added.
917 DEBUG(10,("will try master only\n"));
918 nis_freeresult(result);
919 flags |= MASTER_ONLY;
920 } else
921 break;
923 return result;
926 /***************************************************************
927 Start to enumerate the nisplus passwd list.
928 ****************************************************************/
929 BOOL pdb_setsampwent(BOOL update)
931 char *pfile = smb_passwd_table();
933 pdb_endsampwent(); /* just in case */
934 global_nisp_ent.result = nisp_get_nis_list( pfile, 0 );
935 global_nisp_ent.enum_entry = 0;
936 return global_nisp_ent.result != NULL ? True : False;
939 /***************************************************************
940 End enumeration of the nisplus passwd list.
941 ****************************************************************/
942 void pdb_endsampwent(void)
944 if( global_nisp_ent.result )
945 nis_freeresult(global_nisp_ent.result);
946 global_nisp_ent.result = NULL;
947 global_nisp_ent.enum_entry = 0;
950 /*************************************************************************
951 Routine to return the next entry in the nisplus passwd list.
952 *************************************************************************/
953 BOOL pdb_getsampwent(SAM_ACCOUNT *user)
955 int enum_entry = (int)(global_nisp_ent.enum_entry);
956 nis_result *result = global_nisp_ent.result;
958 if (user==NULL) {
959 DEBUG(0,("SAM_ACCOUNT is NULL.\n"));
960 return False;
963 if (result == NULL ||
964 enum_entry < 0 || enum_entry >= (NIS_RES_NUMOBJ(result) - 1))
966 return False;
969 if(!make_sam_from_nisp_object(user, &NIS_RES_OBJECT(result)[enum_entry]) )
971 DEBUG(0,("Bad SAM_ACCOUNT entry returned from NIS+!\n"));
972 return False;
974 (int)(global_nisp_ent.enum_entry)++;
975 return True;
978 /*************************************************************************
979 Routine to search the nisplus passwd file for an entry matching the username
980 *************************************************************************/
981 BOOL pdb_getsampwnam(SAM_ACCOUNT * user, char *sname)
983 /* Static buffers we will return. */
984 nis_result *result = NULL;
985 pstring nisname;
986 BOOL ret;
987 char *pfile = smb_passwd_table();
988 int i;
990 if (!*pfile)
992 DEBUG(0, ("No SMB password file set\n"));
993 return False;
996 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", sname, pfile);
997 DEBUG(10, ("search by nisname: %s\n", nisname));
999 /* Search the table. */
1001 if(!(result = nisp_get_nis_list(nisname, 0)))
1003 return False;
1006 ret = make_sam_from_nisresult(user, result);
1007 nis_freeresult(result);
1009 return ret;
1012 /*************************************************************************
1013 Routine to search the nisplus passwd file for an entry matching the username
1014 *************************************************************************/
1015 BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
1017 nis_result *result;
1018 char *nisname;
1019 BOOL ret;
1020 char *pfile = smb_passwd_table();
1022 if (!*pfile)
1024 DEBUG(0, ("no SMB password file set\n"));
1025 return False;
1028 nisname = make_nisname_from_user_rid(rid, pfile);
1030 DEBUG(10, ("search by rid: %s\n", nisname));
1032 /* Search the table. */
1034 if(!(result = nisp_get_nis_list(nisname, 0)))
1036 return False;
1039 ret = make_sam_from_nisresult(user, result);
1040 nis_freeresult(result);
1042 return ret;
1045 /*************************************************************************
1046 Routine to remove entry from the nisplus smbpasswd table
1047 *************************************************************************/
1048 BOOL pdb_delete_sam_account(char *sname)
1050 char *pfile = smb_passwd_table();
1051 pstring nisname;
1052 nis_result *result, *delresult;
1053 nis_object *obj;
1054 int i;
1056 if (!*pfile)
1058 DEBUG(0, ("no SMB password file set\n"));
1059 return False;
1062 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", sname, pfile);
1064 /* Search the table. */
1066 if( !(result = nisp_get_nis_list(nisname,
1067 MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
1068 EXPAND_NAME|HARD_LOOKUP))) {
1069 return False;
1072 if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
1073 /* User not found. */
1074 DEBUG(0,("user not found in NIS+\n"));
1075 nis_freeresult(result);
1076 return False;
1079 obj = NIS_RES_OBJECT(result);
1080 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s", sname, obj->zo_name,
1081 obj->zo_domain);
1083 DEBUG(10, ("removing name: %s\n", nisname));
1084 delresult = nis_remove_entry(nisname, obj,
1085 MASTER_ONLY|REM_MULTIPLE|ALL_RESULTS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
1087 nis_freeresult(result);
1089 if(delresult->status != NIS_SUCCESS) {
1090 DEBUG(0, ("NIS+ table update failed: %s %s\n",
1091 nisname, nis_sperrno(delresult->status)));
1092 nis_freeresult(delresult);
1093 return False;
1095 nis_freeresult(delresult);
1096 return True;
1099 /************************************************************************
1100 Routine to add an entry to the nisplus passwd file.
1101 *************************************************************************/
1102 BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
1104 int local_user = 0;
1105 char *pfile = smb_passwd_table();
1106 pstring pfiletmp;
1107 char *nisname;
1108 nis_result *result = NULL, *tblresult = NULL;
1109 nis_object new_obj, *obj;
1110 entry_col *ecol;
1111 int ta_maxcol;
1114 * 1. find user domain.
1115 * a. try nis search in passwd.org_dir - if found use domain from result.
1116 * b. try getpwnam. this may be needed if user is defined
1117 * in /etc/passwd file (or elsewere) and not in passwd.org_dir.
1118 * if found, use host default domain.
1119 * c. exit with False - no such user.
1121 * 2. add user
1122 * a. find smbpasswd table
1123 * search pfile in user domain if not found, try host default
1124 * domain.
1125 * b. smbpasswd domain is found, fill data and add entry.
1131 * Check if user is already there.
1133 safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
1135 if(pdb_get_username(newpwd) != NULL) {
1136 nisname = make_nisname_from_name(pdb_get_username(newpwd),
1137 pfiletmp);
1138 } else {
1139 return False;
1142 if(!(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
1143 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
1144 return False;
1146 if (result->status != NIS_SUCCESS &&
1147 result->status != NIS_NOTFOUND) {
1148 DEBUG(3, ( "nis_list failure: %s: %s\n",
1149 nisname, nis_sperrno(result->status)));
1150 nis_freeresult(result);
1151 return False;
1154 if (result->status == NIS_SUCCESS && NIS_RES_NUMOBJ(result) > 0)
1156 DEBUG(3, ("User already exists in NIS+ password db: %s\n",
1157 pfile));
1158 nis_freeresult(result);
1159 return False;
1162 nis_freeresult(result); /* no such user, free results */
1165 * check for user in unix password database. we need this to get
1166 * domain, where smbpasswd entry should be stored.
1169 #if 1 /* passwd and smbpasswd users should be in the same domain */
1170 nisname = make_nisname_from_name(pdb_get_username(newpwd),
1171 "passwd.org_dir");
1173 result = nisp_get_nis_list(nisname,
1174 MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
1175 EXPAND_NAME|HARD_LOOKUP);
1177 if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0)
1179 DEBUG(3, ("nis_list failure: %s: %s\n",
1180 nisname, nis_sperrno(result->status)));
1181 nis_freeresult(result);
1183 if (!sys_getpwnam(pdb_get_username(newpwd))) {
1184 /* no such user in system! */
1185 return False;
1188 * user is defined, but not in passwd.org_dir.
1190 local_user = 1;
1191 } else {
1192 safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
1193 safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1);
1194 safe_strcat(pfiletmp, NIS_RES_OBJECT(result)->zo_domain,
1195 sizeof(pfiletmp)-strlen(pfiletmp)-1);
1196 nis_freeresult(result); /* not needed any more */
1198 tblresult = nis_lookup(pfiletmp,
1199 MASTER_ONLY|FOLLOW_LINKS|\
1200 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
1203 if (local_user || tblresult->status != NIS_SUCCESS)
1206 * no user domain or
1207 * smbpasswd table not found in user domain, fallback to
1208 * default domain.
1210 if (!local_user) /* free previous failed search result */
1211 nis_freeresult(tblresult);
1212 #endif
1213 tblresult = nis_lookup(pfile, MASTER_ONLY|FOLLOW_LINKS|\
1214 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
1215 if (tblresult->status != NIS_SUCCESS)
1217 /* still nothing. bail out */
1218 nis_freeresult(tblresult);
1219 DEBUG(3, ( "nis_lookup failure: %s\n",
1220 nis_sperrno(tblresult->status)));
1221 return False;
1223 obj = NIS_RES_OBJECT(tblresult);
1224 /* we need full name for nis_add_entry() */
1225 slprintf(pfiletmp, sizeof(pfiletmp)-1, "%s.%s", obj->zo_name,
1226 obj->zo_domain);
1227 #if 1 /* matching } from previous #if */
1229 #endif
1231 memset((char *)&new_obj, 0, sizeof (new_obj));
1232 /* fill entry headers */
1233 /* we do not free these. */
1234 new_obj.zo_name = obj->zo_name;
1235 new_obj.zo_owner = obj->zo_owner;
1236 new_obj.zo_group = obj->zo_group;
1237 new_obj.zo_domain = obj->zo_domain;
1238 /* uints */
1239 new_obj.zo_access = obj->zo_access;
1240 new_obj.zo_ttl = obj->zo_ttl;
1242 new_obj.zo_data.zo_type = ENTRY_OBJ;
1243 new_obj.EN_data.en_type = obj->TA_data.ta_type;
1245 ta_maxcol = obj->TA_data.ta_maxcol;
1247 if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
1248 DEBUG(0, ("memory allocation failure\n"));
1249 nis_freeresult(tblresult);
1250 return False;
1253 memset((char *)ecol, 0, ta_maxcol*sizeof (entry_col));
1254 new_obj.EN_data.en_cols.en_cols_val = ecol;
1255 new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
1257 init_nisp_from_sam(&new_obj, newpwd, NULL);
1259 DEBUG(10, ( "add NIS+ entry: %s\n", nisname));
1260 result = nis_add_entry(pfiletmp, &new_obj, 0);
1262 free(ecol); /* free allocated entry space */
1264 if (result->status != NIS_SUCCESS)
1266 DEBUG(3, ( "NIS+ table update failed: %s\n",
1267 nisname, nis_sperrno(result->status)));
1268 nis_freeresult(tblresult);
1269 nis_freeresult(result);
1270 return False;
1273 nis_freeresult(tblresult);
1274 nis_freeresult(result);
1276 return True;
1279 /************************************************************************
1280 Routine to modify the nisplus passwd entry.
1281 ************************************************************************/
1282 BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override)
1284 nis_result *result, *addresult;
1285 nis_object *obj;
1286 nis_object new_obj;
1287 entry_col *ecol;
1288 int ta_maxcol;
1289 char *pfile = smb_passwd_table();
1290 pstring nisname;
1291 int i;
1293 if (!*pfile)
1295 DEBUG(0, ("no SMB password file set\n"));
1296 return False;
1299 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s",
1300 pdb_get_username(newpwd), pfile);
1302 DEBUG(10, ("search by name: %s\n", nisname));
1304 /* Search the table. */
1306 if( !(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
1307 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
1308 return False;
1311 if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
1312 /* User not found. */
1313 DEBUG(0,("user not found in NIS+\n"));
1314 nis_freeresult(result);
1315 return False;
1318 obj = NIS_RES_OBJECT(result);
1319 DEBUG(6,("entry found in %s\n", obj->zo_domain));
1321 /* we must create new stub object with EN_MODIFIED flag.
1322 this is because obj from result is going to be freed and
1323 we do not want to break it or cause memory leaks or corruption.
1326 memmove((char *)&new_obj, obj, sizeof (new_obj));
1327 ta_maxcol = obj->TA_data.ta_maxcol;
1329 if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
1330 DEBUG(0, ("memory allocation failure\n"));
1331 nis_freeresult(result);
1332 return False;
1335 memmove((char *)ecol, obj->EN_data.en_cols.en_cols_val,
1336 ta_maxcol*sizeof (entry_col));
1337 new_obj.EN_data.en_cols.en_cols_val = ecol;
1338 new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
1340 if ( init_nisp_from_sam(&new_obj, newpwd, obj) == True ) {
1341 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s",
1342 pdb_get_username(newpwd), obj->zo_name, obj->zo_domain);
1344 DEBUG(10, ("NIS+ table update: %s\n", nisname));
1345 addresult =
1346 nis_modify_entry(nisname, &new_obj,
1347 MOD_SAMEOBJ | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP);
1349 if(addresult->status != NIS_SUCCESS) {
1350 DEBUG(0, ("NIS+ table update failed: %s %s\n",
1351 nisname, nis_sperrno(addresult->status)));
1352 nis_freeresult(addresult);
1353 nis_freeresult(result);
1354 free(ecol);
1355 return False;
1358 DEBUG(6,("password changed\n"));
1359 nis_freeresult(addresult);
1360 } else {
1361 DEBUG(6,("nothing to change!\n"));
1364 free(ecol);
1365 nis_freeresult(result);
1367 return True;
1370 #else
1371 void nisplus_dummy_function(void);
1372 void nisplus_dummy_function(void) { } /* stop some compilers complaining */
1373 #endif /* WITH_NISPLUSSAM */