fix for compiling
[Samba.git] / source / passdb / pdb_nisplus.c
blobe168e487f752611e92c17cf0830c51f9aae1c4c4
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 safe_strcpy(nisname, "[user_rid=", sizeof(nisname)-1);
134 slprintf(nisname, sizeof(nisname)-1, "%s%d", nisname, rid);
135 safe_strcat(nisname, "],", sizeof(nisname)-strlen(nisname)-1);
136 safe_strcat(nisname, pfile, sizeof(nisname)-strlen(nisname)-1);
138 return nisname;
141 /***************************************************************
142 make_nisname_from_uid
143 ****************************************************************/
144 static char *make_nisname_from_uid(int uid, char *pfile)
146 static pstring nisname;
148 safe_strcpy(nisname, "[uid=", sizeof(nisname)-1);
149 slprintf(nisname, sizeof(nisname)-1, "%s%d", nisname, uid);
150 safe_strcat(nisname, "],", sizeof(nisname)-strlen(nisname)-1);
151 safe_strcat(nisname, pfile, sizeof(nisname)-strlen(nisname)-1);
153 return nisname;
156 /***************************************************************
157 make_nisname_from_name
158 ****************************************************************/
159 static char *make_nisname_from_name(char *user_name, char *pfile)
161 static pstring nisname;
163 safe_strcpy(nisname, "[name=", sizeof(nisname)-1);
164 safe_strcat(nisname, user_name, sizeof(nisname) - strlen(nisname) - 1);
165 safe_strcat(nisname, "],", sizeof(nisname)-strlen(nisname)-1);
166 safe_strcat(nisname, pfile, sizeof(nisname)-strlen(nisname)-1);
168 return nisname;
171 /*************************************************************************
172 gets a NIS+ attribute
173 *************************************************************************/
174 static void get_single_attribute(nis_object *new_obj, int col,
175 char *val, int len)
177 int entry_len;
179 if (new_obj == NULL || val == NULL) return;
181 entry_len = ENTRY_LEN(new_obj, col);
182 if (len > entry_len)
184 len = entry_len;
187 safe_strcpy(val, ENTRY_VAL(new_obj, col), len-1);
190 /************************************************************************
191 makes a struct sam_passwd from a NIS+ object.
192 ************************************************************************/
193 static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, nis_object *obj)
195 char *ptr;
196 pstring full_name; /* this must be translated to dos code page */
197 pstring acct_desc; /* this must be translated to dos code page */
198 pstring home_dir; /* set default value from smb.conf for user */
199 pstring home_drive; /* set default value from smb.conf for user */
200 pstring logon_script; /* set default value from smb.conf for user */
201 pstring profile_path; /* set default value from smb.conf for user */
202 pstring hours;
203 int hours_len;
204 unsigned char smbpwd[16];
205 unsigned char smbntpwd[16];
209 * time values. note: this code assumes 32bit time_t!
212 pdb_set_logon_time(pw_buf, (time_t)0);
213 ptr = (uchar *)ENTRY_VAL(obj, NPF_LOGON_T);
214 if(ptr && *ptr && (StrnCaseCmp(ptr, "LNT-", 4)==0)) {
215 int i;
216 ptr += 4;
217 for(i = 0; i < 8; i++) {
218 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
219 break;
221 if(i == 8) {
222 pdb_set_logon_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
226 pdb_set_logoff_time(pw_buf, get_time_t_max());
227 ptr = (uchar *)ENTRY_VAL(obj, NPF_LOGOFF_T);
228 if(ptr && *ptr && (StrnCaseCmp(ptr, "LOT-", 4)==0)) {
229 int i;
230 ptr += 4;
231 for(i = 0; i < 8; i++) {
232 if(ptr[i] == '\0' || !isxdigit(ptr[i]))
233 break;
235 if(i == 8) {
236 pdb_set_logoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
240 pdb_set_kickoff_time(pw_buf, get_time_t_max());
241 ptr = (uchar *)ENTRY_VAL(obj, NPF_KICK_T);
242 if(ptr && *ptr && (StrnCaseCmp(ptr, "KOT-", 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_kickoff_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
254 pdb_set_pass_last_set_time(pw_buf, (time_t)0);
255 ptr = (uchar *)ENTRY_VAL(obj, NPF_PWDLSET_T);
256 if(ptr && *ptr && (StrnCaseCmp(ptr, "LCT-", 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_pass_last_set_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
268 pdb_set_pass_can_change_time(pw_buf, (time_t)0);
269 ptr = (uchar *)ENTRY_VAL(obj, NPF_PWDCCHG_T);
270 if(ptr && *ptr && (StrnCaseCmp(ptr, "CCT-", 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_pass_can_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
282 pdb_set_pass_must_change_time(pw_buf, get_time_t_max()); /* Password never expires. */
283 ptr = (uchar *)ENTRY_VAL(obj, NPF_PWDMCHG_T);
284 if(ptr && *ptr && (StrnCaseCmp(ptr, "MCT-", 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_must_change_time(pw_buf, (time_t)strtol(ptr, NULL, 16));
296 /* string values */
297 pdb_set_username(pw_buf, ENTRY_VAL(obj, NPF_NAME));
298 pdb_set_domain(pw_buf, lp_workgroup());
299 /* pdb_set_nt_username() -- cant set it here... */
301 get_single_attribute(obj, NPF_FULL_NAME, full_name, sizeof(pstring));
302 unix_to_dos(full_name, True);
303 pdb_set_fullname(pw_buf, full_name);
305 pdb_set_acct_ctrl(pw_buf, pdb_decode_acct_ctrl(ENTRY_VAL(obj,
306 NPF_ACB)));
308 get_single_attribute(obj, NPF_ACCT_DESC, acct_desc, sizeof(pstring));
309 unix_to_dos(acct_desc, True);
310 pdb_set_acct_desc(pw_buf, acct_desc);
312 pdb_set_workstations(pw_buf, ENTRY_VAL(obj, NPF_WORKSTATIONS));
313 pdb_set_munged_dial(pw_buf, NULL);
315 pdb_set_uid(pw_buf, atoi(ENTRY_VAL(obj, NPF_UID)));
316 pdb_set_gid(pw_buf, atoi(ENTRY_VAL(obj, NPF_SMB_GRPID)));
317 pdb_set_user_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_USER_RID)));
318 pdb_set_group_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_GROUP_RID)));
320 /* values, must exist for user */
321 if( !(pdb_get_acct_ctrl(pw_buf) & ACB_WSTRUST) ) {
322 /* FIXME!! This doesn't belong here.
323 Should be set in net_sam_logon()
324 --jerry */
325 pstrcpy(samlogon_user, pdb_get_username(pw_buf));
327 get_single_attribute(obj, NPF_HOME_DIR, home_dir, sizeof(pstring));
328 if( !(home_dir && *home_dir) ) {
329 pstrcpy(home_dir, lp_logon_home());
330 pdb_set_homedir(pw_buf, home_dir, False);
332 else
333 pdb_set_homedir(pw_buf, home_dir, True);
335 get_single_attribute(obj, NPF_DIR_DRIVE, home_drive, sizeof(pstring));
336 if( !(home_drive && *home_drive) ) {
337 pstrcpy(home_drive, lp_logon_drive());
338 pdb_set_dir_drive(pw_buf, home_drive, False);
340 else
341 pdb_set_dir_drive(pw_buf, home_drive, True);
343 get_single_attribute(obj, NPF_LOGON_SCRIPT, logon_script,
344 sizeof(pstring));
345 if( !(logon_script && *logon_script) ) {
346 pstrcpy(logon_script, lp_logon_script());
348 else
349 pdb_set_logon_script(pw_buf, logon_script, True);
351 get_single_attribute(obj, NPF_PROFILE_PATH, profile_path, sizeof(pstring));
352 if( !(profile_path && *profile_path) ) {
353 pstrcpy(profile_path, lp_logon_path());
354 pdb_set_profile_path(pw_buf, profile_path, False);
356 else
357 pdb_set_profile_path(pw_buf, profile_path, True);
360 else
362 /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
363 pdb_set_group_rid (pw_buf, DOMAIN_GROUP_RID_USERS);
366 /* Check the lanman password column. */
367 ptr = (char *)ENTRY_VAL(obj, NPF_LMPWD);
368 if (!pdb_set_lanman_passwd(pw_buf, NULL))
369 return False;
371 if (!strncasecmp(ptr, "NO PASSWORD", 11)) {
372 pdb_set_acct_ctrl(pw_buf, pdb_get_acct_ctrl(pw_buf) | ACB_PWNOTREQ);
373 } else {
374 if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbpwd)) {
375 DEBUG(0, ("malformed LM pwd entry: %s.\n",
376 pdb_get_username(pw_buf)));
377 return False;
379 if (!pdb_set_lanman_passwd(pw_buf, smbpwd))
380 return False;
383 /* Check the NT password column. */
384 ptr = ENTRY_VAL(obj, NPF_NTPWD);
385 if (!pdb_set_nt_passwd(pw_buf, NULL))
386 return False;
388 if (!(pdb_get_acct_ctrl(pw_buf) & ACB_PWNOTREQ) &&
389 strncasecmp(ptr, "NO PASSWORD", 11)) {
390 if (strlen(ptr) != 32 || !pdb_gethexpwd(ptr, smbntpwd)) {
391 DEBUG(0, ("malformed NT pwd entry:\
392 uid = %d.\n",
393 pdb_get_uid(pw_buf)));
394 return False;
396 if (!pdb_set_nt_passwd(pw_buf, smbntpwd))
397 return False;
400 pdb_set_unknown_3(pw_buf, 0xffffff); /* don't know */
401 pdb_set_logon_divs(pw_buf, 168); /* hours per week */
403 if( (hours_len = ENTRY_LEN(obj, NPF_HOURS)) == 21 ) {
404 memcpy(hours, ENTRY_VAL(obj, NPF_HOURS), hours_len);
405 } else {
406 hours_len = 21; /* 21 times 8 bits = 168 */
407 /* available at all hours */
408 memset(hours, 0xff, hours_len);
410 pdb_set_hours_len(pw_buf, hours_len);
411 pdb_set_hours(pw_buf, hours);
413 pdb_set_unknown_5(pw_buf, 0x00020000); /* don't know */
414 pdb_set_unknown_6(pw_buf, 0x000004ec); /* don't know */
416 return True;
419 /************************************************************************
420 makes a struct sam_passwd from a NIS+ result.
421 ************************************************************************/
422 static BOOL make_sam_from_nisresult(SAM_ACCOUNT *pw_buf, nis_result *result)
424 if (pw_buf == NULL || result == NULL) return False;
426 if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND)
428 DEBUG(0, ("NIS+ lookup failure: %s\n",
429 nis_sperrno(result->status)));
430 return False;
433 /* User not found. */
434 if (NIS_RES_NUMOBJ(result) <= 0)
436 DEBUG(10, ("user not found in NIS+\n"));
437 return False;
440 if (NIS_RES_NUMOBJ(result) > 1)
442 DEBUG(10, ("WARNING: Multiple entries for user in NIS+ table!\n"));
445 /* Grab the first hit. */
446 return make_sam_from_nisp_object(pw_buf, &NIS_RES_OBJECT(result)[0]);
449 /*************************************************************************
450 sets a NIS+ attribute
451 *************************************************************************/
452 static void set_single_attribute(nis_object *new_obj, int col,
453 char *val, int len, int flags)
455 if (new_obj == NULL) return;
457 ENTRY_VAL(new_obj, col) = val;
458 ENTRY_LEN(new_obj, col) = len+1;
460 if (flags != 0)
462 new_obj->EN_data.en_cols.en_cols_val[col].ec_flags = flags;
466 /***************************************************************
467 copy or modify nis object. this object is used to add or update
468 nisplus table entry.
469 ****************************************************************/
470 static BOOL init_nisp_from_sam(nis_object *obj, SAM_ACCOUNT *sampass,
471 nis_object *old)
474 * Fill nis_object for entry add or update.
475 * if we are updateing, we have to find out differences and set
476 * EN_MODIFIED flag. also set need_to_modify to trigger
477 * nis_modify_entry() call in pdb_update_sam_account().
479 * TODO:
480 * get data from SAM
481 * if (modify) get data from nis_object, compare and store if
482 * different + set EN_MODIFIED and need_to_modify
483 * else
484 * store
486 BOOL need_to_modify = False;
487 char *name; /* from SAM */
488 /* these must be static or allocate and free entry columns! */
489 static fstring uid; /* from SAM */
490 static fstring user_rid; /* from SAM */
491 static fstring gid; /* from SAM */
492 static fstring group_rid; /* from SAM */
493 char *acb; /* from SAM */
494 static fstring smb_passwd; /* from SAM */
495 static fstring smb_nt_passwd; /* from SAM */
496 static fstring logon_t; /* from SAM */
497 static fstring logoff_t; /* from SAM */
498 static fstring kickoff_t; /* from SAM */
499 static fstring pwdlset_t; /* from SAM */
500 static fstring pwdlchg_t; /* from SAM */
501 static fstring pwdmchg_t; /* from SAM */
502 static fstring full_name; /* from SAM */
503 static fstring acct_desc; /* from SAM */
504 static char empty[1]; /* just an empty string */
507 name = pdb_get_username(sampass);
508 slprintf(uid, sizeof(uid)-1, "%u", pdb_get_uid(sampass));
509 slprintf(user_rid, sizeof(user_rid)-1, "%u",
510 pdb_get_user_rid(sampass)? pdb_get_user_rid(sampass):
511 pdb_uid_to_user_rid(pdb_get_uid(sampass)));
512 slprintf(gid, sizeof(gid)-1, "%u", pdb_get_gid(sampass));
513 slprintf(group_rid, sizeof(group_rid)-1, "%u",
514 pdb_get_group_rid(sampass)? pdb_get_group_rid(sampass):
515 pdb_gid_to_group_rid(pdb_get_gid(sampass)));
516 acb = pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sampass),
517 NEW_PW_FORMAT_SPACE_PADDED_LEN);
518 pdb_sethexpwd (smb_passwd, pdb_get_lanman_passwd(sampass),
519 pdb_get_acct_ctrl(sampass));
520 pdb_sethexpwd (smb_nt_passwd, pdb_get_nt_passwd(sampass),
521 pdb_get_acct_ctrl(sampass));
522 slprintf(logon_t, 13, "LNT-%08X",
523 (uint32)pdb_get_logon_time(sampass));
524 slprintf(logoff_t, 13, "LOT-%08X",
525 (uint32)pdb_get_logoff_time(sampass));
526 slprintf(kickoff_t, 13, "KOT-%08X",
527 (uint32)pdb_get_kickoff_time(sampass));
528 slprintf(pwdlset_t, 13, "LCT-%08X",
529 (uint32)pdb_get_pass_last_set_time(sampass));
530 slprintf(pwdlchg_t, 13, "CCT-%08X",
531 (uint32)pdb_get_pass_can_change_time(sampass));
532 slprintf(pwdmchg_t, 13, "MCT-%08X",
533 (uint32)pdb_get_pass_must_change_time(sampass));
534 safe_strcpy(full_name, pdb_get_fullname(sampass), sizeof(full_name)-1);
535 dos_to_unix(full_name, True);
536 safe_strcpy(acct_desc, pdb_get_acct_desc(sampass), sizeof(acct_desc)-1);
537 dos_to_unix(acct_desc, True);
539 if( old ) {
540 /* name */
541 if(strcmp(ENTRY_VAL(old, NPF_NAME), name))
543 need_to_modify = True;
544 set_single_attribute(obj, NPF_NAME, name, strlen(name),
545 EN_MODIFIED);
549 /* uid */
550 if(pdb_get_uid(sampass) != -1) {
551 if(!ENTRY_VAL(old, NPF_UID) || strcmp(ENTRY_VAL(old, NPF_UID), uid))
553 need_to_modify = True;
554 set_single_attribute(obj, NPF_UID, uid,
555 strlen(uid), EN_MODIFIED);
559 /* user_rid */
560 if (pdb_get_user_rid(sampass)) {
561 if(!ENTRY_VAL(old, NPF_USER_RID) ||
562 strcmp(ENTRY_VAL(old, NPF_USER_RID), user_rid) ) {
563 need_to_modify = True;
564 set_single_attribute(obj, NPF_USER_RID, user_rid,
565 strlen(user_rid), EN_MODIFIED);
569 /* smb_grpid */
570 if (pdb_get_gid(sampass) != -1) {
571 if(!ENTRY_VAL(old, NPF_SMB_GRPID) ||
572 strcmp(ENTRY_VAL(old, NPF_SMB_GRPID), gid) ) {
573 need_to_modify = True;
574 set_single_attribute(obj, NPF_SMB_GRPID, gid,
575 strlen(gid), EN_MODIFIED);
579 /* group_rid */
580 if (pdb_get_group_rid(sampass)) {
581 if(!ENTRY_VAL(old, NPF_GROUP_RID) ||
582 strcmp(ENTRY_VAL(old, NPF_GROUP_RID), group_rid) ) {
583 need_to_modify = True;
584 set_single_attribute(obj, NPF_GROUP_RID, group_rid,
585 strlen(group_rid), EN_MODIFIED);
589 /* acb */
590 if (!ENTRY_VAL(old, NPF_ACB) ||
591 strcmp(ENTRY_VAL(old, NPF_ACB), acb)) {
592 need_to_modify = True;
593 set_single_attribute(obj, NPF_ACB, acb, strlen(acb), EN_MODIFIED);
596 /* lmpwd */
597 if(!ENTRY_VAL(old, NPF_LMPWD) ||
598 strcmp(ENTRY_VAL(old, NPF_LMPWD), smb_passwd) ) {
599 need_to_modify = True;
600 set_single_attribute(obj, NPF_LMPWD, smb_passwd,
601 strlen(smb_passwd), EN_CRYPT|EN_MODIFIED);
604 /* ntpwd */
605 if(!ENTRY_VAL(old, NPF_NTPWD) ||
606 strcmp(ENTRY_VAL(old, NPF_NTPWD), smb_nt_passwd) ) {
607 need_to_modify = True;
608 set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd,
609 strlen(smb_nt_passwd), EN_CRYPT|EN_MODIFIED);
612 /* logon_t */
613 if( pdb_get_logon_time(sampass) &&
614 (!ENTRY_VAL(old, NPF_LOGON_T) ||
615 strcmp(ENTRY_VAL(old, NPF_LOGON_T), logon_t ))) {
616 need_to_modify = True;
617 set_single_attribute(obj, NPF_LOGON_T, logon_t,
618 strlen(logon_t), EN_MODIFIED);
621 /* logoff_t */
622 if( pdb_get_logoff_time(sampass) &&
623 (!ENTRY_VAL(old, NPF_LOGOFF_T) ||
624 strcmp(ENTRY_VAL(old, NPF_LOGOFF_T), logoff_t))) {
625 need_to_modify = True;
626 set_single_attribute(obj, NPF_LOGOFF_T, logoff_t,
627 strlen(logoff_t), EN_MODIFIED);
630 /* kick_t */
631 if( pdb_get_kickoff_time(sampass) &&
632 (!ENTRY_VAL(old, NPF_KICK_T) ||
633 strcmp(ENTRY_VAL(old, NPF_KICK_T), kickoff_t))) {
634 need_to_modify = True;
635 set_single_attribute(obj, NPF_KICK_T, kickoff_t,
636 strlen(kickoff_t), EN_MODIFIED);
639 /* pwdlset_t */
640 if( pdb_get_pass_last_set_time(sampass) &&
641 (!ENTRY_VAL(old, NPF_PWDLSET_T) ||
642 strcmp(ENTRY_VAL(old, NPF_PWDLSET_T), pwdlset_t))) {
643 need_to_modify = True;
644 set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t,
645 strlen(pwdlset_t), EN_MODIFIED);
648 /* pwdlchg_t */
649 if( pdb_get_pass_can_change_time(sampass) &&
650 (!ENTRY_VAL(old, NPF_PWDCCHG_T) ||
651 strcmp(ENTRY_VAL(old, NPF_PWDCCHG_T), pwdlchg_t))) {
652 need_to_modify = True;
653 set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t,
654 strlen(pwdlchg_t), EN_MODIFIED);
657 /* pwdmchg_t */
658 if( pdb_get_pass_must_change_time(sampass) &&
659 (!ENTRY_VAL(old, NPF_PWDMCHG_T) ||
660 strcmp(ENTRY_VAL(old, NPF_PWDMCHG_T), pwdmchg_t))) {
661 need_to_modify = True;
662 set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t,
663 strlen(pwdmchg_t), EN_MODIFIED);
666 /* full_name */
667 /* must support set, unset and change */
668 if ( (pdb_get_fullname(sampass) &&
669 !ENTRY_VAL(old, NPF_FULL_NAME)) ||
670 (ENTRY_VAL(old, NPF_FULL_NAME) &&
671 !pdb_get_fullname(sampass)) ||
672 (ENTRY_VAL(old, NPF_FULL_NAME) &&
673 pdb_get_fullname(sampass) &&
674 strcmp( ENTRY_VAL(old, NPF_FULL_NAME), full_name ))) {
675 need_to_modify = True;
676 set_single_attribute(obj, NPF_FULL_NAME, full_name,
677 strlen(full_name), EN_MODIFIED);
680 /* home_dir */
681 /* must support set, unset and change */
682 if( (pdb_get_homedir(sampass) &&
683 !ENTRY_VAL(old, NPF_HOME_DIR)) ||
684 (ENTRY_VAL(old, NPF_HOME_DIR) &&
685 !pdb_get_homedir(sampass)) ||
686 (ENTRY_VAL(old, NPF_HOME_DIR) &&
687 pdb_get_homedir(sampass) &&
688 strcmp( ENTRY_VAL(old, NPF_HOME_DIR),
689 pdb_get_homedir(sampass)))) {
690 need_to_modify = True;
691 set_single_attribute(obj, NPF_HOME_DIR, pdb_get_homedir(sampass),
692 strlen(pdb_get_homedir(sampass)), EN_MODIFIED);
695 /* dir_drive */
696 /* must support set, unset and change */
697 if( (pdb_get_dirdrive(sampass) &&
698 !ENTRY_VAL(old, NPF_DIR_DRIVE)) ||
699 (ENTRY_VAL(old, NPF_DIR_DRIVE) &&
700 !pdb_get_dirdrive(sampass)) ||
701 (ENTRY_VAL(old, NPF_DIR_DRIVE) &&
702 pdb_get_dirdrive(sampass) &&
703 strcmp( ENTRY_VAL(old, NPF_DIR_DRIVE),
704 pdb_get_dirdrive(sampass)))) {
705 need_to_modify = True;
706 set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dirdrive(sampass),
707 strlen(pdb_get_dirdrive(sampass)), EN_MODIFIED);
710 /* logon_script */
711 /* must support set, unset and change */
712 if( (pdb_get_logon_script(sampass) &&
713 !ENTRY_VAL(old, NPF_LOGON_SCRIPT) ||
714 (ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
715 !pdb_get_logon_script(sampass)) ||
716 ( ENTRY_VAL(old, NPF_LOGON_SCRIPT) &&
717 pdb_get_logon_script(sampass) &&
718 strcmp( ENTRY_VAL(old, NPF_LOGON_SCRIPT),
719 pdb_get_logon_script(sampass))))) {
720 need_to_modify = True;
721 set_single_attribute(obj, NPF_LOGON_SCRIPT,
722 pdb_get_logon_script(sampass),
723 strlen(pdb_get_logon_script(sampass)),
724 EN_MODIFIED);
727 /* profile_path */
728 /* must support set, unset and change */
729 if( (pdb_get_profile_path(sampass) &&
730 !ENTRY_VAL(old, NPF_PROFILE_PATH)) ||
731 (ENTRY_VAL(old, NPF_PROFILE_PATH) &&
732 !pdb_get_profile_path(sampass)) ||
733 (ENTRY_VAL(old, NPF_PROFILE_PATH) &&
734 pdb_get_profile_path(sampass) &&
735 strcmp( ENTRY_VAL(old, NPF_PROFILE_PATH),
736 pdb_get_profile_path(sampass) ) )) {
737 need_to_modify = True;
738 set_single_attribute(obj, NPF_PROFILE_PATH,
739 pdb_get_profile_path(sampass),
740 strlen(pdb_get_profile_path(sampass)),
741 EN_MODIFIED);
744 /* acct_desc */
745 /* must support set, unset and change */
746 if( (pdb_get_acct_desc(sampass) &&
747 !ENTRY_VAL(old, NPF_ACCT_DESC)) ||
748 (ENTRY_VAL(old, NPF_ACCT_DESC) &&
749 !pdb_get_acct_desc(sampass)) ||
750 (ENTRY_VAL(old, NPF_ACCT_DESC) &&
751 pdb_get_acct_desc(sampass) &&
752 strcmp( ENTRY_VAL(old, NPF_ACCT_DESC), acct_desc ) )) {
753 need_to_modify = True;
754 set_single_attribute(obj, NPF_ACCT_DESC, acct_desc,
755 strlen(acct_desc), EN_MODIFIED);
758 /* workstations */
759 /* must support set, unset and change */
760 if ( (pdb_get_workstations(sampass) &&
761 !ENTRY_VAL(old, NPF_WORKSTATIONS) ) ||
762 (ENTRY_VAL(old, NPF_WORKSTATIONS) &&
763 !pdb_get_workstations(sampass)) ||
764 (ENTRY_VAL(old, NPF_WORKSTATIONS) &&
765 pdb_get_workstations(sampass)) &&
766 strcmp( ENTRY_VAL(old, NPF_WORKSTATIONS),
767 pdb_get_workstations(sampass))) {
768 need_to_modify = True;
769 set_single_attribute(obj, NPF_WORKSTATIONS,
770 pdb_get_workstations(sampass),
771 strlen(pdb_get_workstations(sampass)),
772 EN_MODIFIED);
775 /* hours */
776 if ((pdb_get_hours_len(sampass) != ENTRY_LEN(old, NPF_HOURS)) ||
777 memcmp(pdb_get_hours(sampass), ENTRY_VAL(old, NPF_HOURS),
778 ENTRY_LEN(old, NPF_HOURS))) {
779 need_to_modify = True;
780 /* set_single_attribute will add 1 for len ... */
781 set_single_attribute(obj, NPF_HOURS, pdb_get_hours(sampass),
782 pdb_get_hours_len(sampass)-1, EN_MODIFIED);
784 } else {
785 char *homedir, *dirdrive, *logon_script, *profile_path, *workstations;
787 *empty = '\0'; /* empty string */
789 set_single_attribute(obj, NPF_NAME, name, strlen(name), 0);
790 set_single_attribute(obj, NPF_UID, uid, strlen(uid), 0);
791 set_single_attribute(obj, NPF_USER_RID, user_rid,
792 strlen(user_rid), 0);
793 set_single_attribute(obj, NPF_SMB_GRPID, gid, strlen(gid), 0);
794 set_single_attribute(obj, NPF_GROUP_RID, group_rid,
795 strlen(group_rid), 0);
796 set_single_attribute(obj, NPF_ACB, acb, strlen(acb), 0);
797 set_single_attribute(obj, NPF_LMPWD, smb_passwd,
798 strlen(smb_passwd), EN_CRYPT);
799 set_single_attribute(obj, NPF_NTPWD, smb_nt_passwd,
800 strlen(smb_nt_passwd), EN_CRYPT);
801 set_single_attribute(obj, NPF_LOGON_T, logon_t,
802 strlen(logon_t), 0);
803 set_single_attribute(obj, NPF_LOGOFF_T, logoff_t,
804 strlen(logoff_t), 0);
805 set_single_attribute(obj, NPF_KICK_T, kickoff_t,
806 strlen(kickoff_t),0);
807 set_single_attribute(obj, NPF_PWDLSET_T, pwdlset_t,
808 strlen(pwdlset_t), 0);
809 set_single_attribute(obj, NPF_PWDCCHG_T, pwdlchg_t,
810 strlen(pwdlchg_t), 0);
811 set_single_attribute(obj, NPF_PWDMCHG_T, pwdmchg_t,
812 strlen(pwdmchg_t), 0);
813 set_single_attribute(obj, NPF_FULL_NAME ,
814 full_name, strlen(full_name), 0);
816 if(!(homedir = pdb_get_homedir(sampass)))
817 homedir = empty;
819 set_single_attribute(obj, NPF_HOME_DIR,
820 homedir, strlen(homedir), 0);
822 if(!(dirdrive = pdb_get_dirdrive(sampass)))
823 dirdrive = empty;
825 set_single_attribute(obj, NPF_DIR_DRIVE,
826 dirdrive, strlen(dirdrive), 0);
828 if(!(logon_script = pdb_get_logon_script(sampass)))
829 logon_script = empty;
831 set_single_attribute(obj, NPF_LOGON_SCRIPT,
832 logon_script, strlen(logon_script), 0);
834 if(!(profile_path = pdb_get_profile_path(sampass)))
835 profile_path = empty;
837 set_single_attribute(obj, NPF_PROFILE_PATH,
838 profile_path, strlen(profile_path), 0);
840 set_single_attribute(obj, NPF_ACCT_DESC,
841 acct_desc, strlen(acct_desc), 0);
843 if(!(workstations = pdb_get_workstations(sampass)))
844 workstations = empty;
846 set_single_attribute(obj, NPF_WORKSTATIONS,
847 workstations, strlen(workstations), 0);
849 /* set_single_attribute will add 1 for len ... */
850 set_single_attribute(obj, NPF_HOURS,
851 pdb_get_hours(sampass),
852 pdb_get_hours_len(sampass)-1, 0);
855 return need_to_modify;
858 /***************************************************************
859 calls nis_list, returns results.
860 ****************************************************************/
861 static nis_result *nisp_get_nis_list(char *nis_name, uint_t flags)
863 nis_result *result;
864 int i;
866 if( ! flags)
867 flags = FOLLOW_LINKS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP;
869 for(i = 0; i<2;i++ ) {
870 alarm(60); /* hopefully ok for long searches */
871 result = nis_list(nis_name, flags,NULL,NULL);
873 alarm(0);
874 CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
876 if (gotalarm)
878 DEBUG(0,("NIS+ lookup time out\n"));
879 nis_freeresult(result);
880 return NULL;
882 if( !(flags & MASTER_ONLY) && NIS_RES_NUMOBJ(result) <= 0 ) {
883 /* nis replicas are not in sync perhaps?
884 * this can happen, if account was just added.
886 DEBUG(10,("will try master only\n"));
887 nis_freeresult(result);
888 flags |= MASTER_ONLY;
889 } else
890 break;
892 return result;
895 /***************************************************************
896 Start to enumerate the nisplus passwd list.
897 ****************************************************************/
898 BOOL pdb_setsampwent(BOOL update)
900 char *sp, * p = lp_smb_passwd_file();
901 pstring pfiletmp;
903 if( (sp = strrchr( p, '/' )) )
904 safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1);
905 else
906 safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1);
907 safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1);
909 pdb_endsampwent(); /* just in case */
910 global_nisp_ent.result = nisp_get_nis_list( pfiletmp, 0 );
911 global_nisp_ent.enum_entry = 0;
912 return global_nisp_ent.result != NULL ? True : False;
915 /***************************************************************
916 End enumeration of the nisplus passwd list.
917 ****************************************************************/
918 void pdb_endsampwent(void)
920 if( global_nisp_ent.result )
921 nis_freeresult(global_nisp_ent.result);
922 global_nisp_ent.result = NULL;
923 global_nisp_ent.enum_entry = 0;
926 /*************************************************************************
927 Routine to return the next entry in the nisplus passwd list.
928 *************************************************************************/
929 BOOL pdb_getsampwent(SAM_ACCOUNT *user)
931 int enum_entry = (int)(global_nisp_ent.enum_entry);
932 nis_result *result = global_nisp_ent.result;
934 if (user==NULL) {
935 DEBUG(0,("SAM_ACCOUNT is NULL.\n"));
936 return False;
939 if (result == NULL ||
940 enum_entry < 0 || enum_entry >= (NIS_RES_NUMOBJ(result) - 1))
942 return False;
945 if(!make_sam_from_nisp_object(user, &NIS_RES_OBJECT(result)[enum_entry]) )
947 DEBUG(0,("Bad SAM_ACCOUNT entry returned from NIS+!\n"));
948 return False;
950 (int)(global_nisp_ent.enum_entry)++;
951 return True;
954 /*************************************************************************
955 Routine to search the nisplus passwd file for an entry matching the username
956 *************************************************************************/
957 BOOL pdb_getsampwnam(SAM_ACCOUNT * user, char *sname)
959 /* Static buffers we will return. */
960 nis_result *result = NULL;
961 pstring nisname;
962 BOOL ret;
963 char *pfile = lp_smb_passwd_file();
964 int i;
966 if (!*pfile)
968 DEBUG(0, ("No SMB password file set\n"));
969 return False;
971 if( strrchr( pfile, '/') )
972 pfile = strrchr( pfile, '/') + 1;
974 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir", sname, pfile);
975 DEBUG(10, ("search by nisname: %s\n", nisname));
977 /* Search the table. */
979 if(!(result = nisp_get_nis_list(nisname, 0)))
981 return False;
984 ret = make_sam_from_nisresult(user, result);
985 nis_freeresult(result);
987 return ret;
990 /*************************************************************************
991 Routine to search the nisplus passwd file for an entry matching the username
992 *************************************************************************/
993 BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
995 nis_result *result;
996 char *nisname;
997 BOOL ret;
998 char *sp, *p = lp_smb_passwd_file();
999 pstring pfiletmp;
1001 if (!*p)
1003 DEBUG(0, ("no SMB password file set\n"));
1004 return False;
1007 if( (sp = strrchr( p, '/' )) )
1008 safe_strcpy(pfiletmp, sp+1, sizeof(pfiletmp)-1);
1009 else
1010 safe_strcpy(pfiletmp, p, sizeof(pfiletmp)-1);
1011 safe_strcat(pfiletmp, ".org_dir", sizeof(pfiletmp)-strlen(pfiletmp)-1);
1013 nisname = make_nisname_from_user_rid(rid, pfiletmp);
1015 DEBUG(10, ("search by rid: %s\n", nisname));
1017 /* Search the table. */
1019 if(!(result = nisp_get_nis_list(nisname, 0)))
1021 return False;
1024 ret = make_sam_from_nisresult(user, result);
1025 nis_freeresult(result);
1027 return ret;
1030 /*************************************************************************
1031 Routine to remove entry from the nisplus smbpasswd table
1032 *************************************************************************/
1033 BOOL pdb_delete_sam_account(char *sname)
1035 char *pfile = lp_smb_passwd_file();
1036 pstring nisname;
1037 nis_result *result, *delresult;
1038 nis_object *obj;
1039 int i;
1041 if (!*pfile)
1043 DEBUG(0, ("no SMB password file set\n"));
1044 return False;
1046 if( strrchr( pfile, '/') )
1047 pfile = strrchr( pfile, '/') + 1;
1049 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir", sname, pfile);
1051 /* Search the table. */
1053 if( !(result = nisp_get_nis_list(nisname,
1054 MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
1055 EXPAND_NAME|HARD_LOOKUP))) {
1056 return False;
1059 if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
1060 /* User not found. */
1061 DEBUG(0,("user not found in NIS+\n"));
1062 nis_freeresult(result);
1063 return False;
1066 obj = NIS_RES_OBJECT(result);
1067 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s", sname, obj->zo_name,
1068 obj->zo_domain);
1070 DEBUG(10, ("removing name: %s\n", nisname));
1071 delresult = nis_remove_entry(nisname, obj,
1072 MASTER_ONLY|REM_MULTIPLE|ALL_RESULTS|FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
1074 nis_freeresult(result);
1076 if(delresult->status != NIS_SUCCESS) {
1077 DEBUG(0, ("NIS+ table update failed: %s %s\n",
1078 nisname, nis_sperrno(delresult->status)));
1079 nis_freeresult(delresult);
1080 return False;
1082 nis_freeresult(delresult);
1083 return True;
1086 /************************************************************************
1087 Routine to add an entry to the nisplus passwd file.
1088 *************************************************************************/
1089 BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
1091 int local_user = 0;
1092 char *pfile;
1093 pstring pfiletmp;
1094 char *nisname;
1095 nis_result *result = NULL,
1096 *tblresult = NULL;
1097 nis_object new_obj;
1098 entry_col *ecol;
1099 int ta_maxcol;
1102 * 1. find user domain.
1103 * a. try nis search in passwd.org_dir - if found use domain from result.
1104 * b. try getpwnam. this may be needed if user is defined
1105 * in /etc/passwd file (or elsewere) and not in passwd.org_dir.
1106 * if found, use host default domain.
1107 * c. exit with False - no such user.
1109 * 2. add user
1110 * a. find smbpasswd table
1111 * search pfile in user domain if not found, try host default
1112 * domain.
1113 * b. smbpasswd domain is found, fill data and add entry.
1115 * pfile should contain ONLY table name, org_dir will be concated.
1116 * so, at first we will clear path prefix from pfile, and
1117 * then we will use pfiletmp as playground to put together full
1118 * nisname string.
1119 * such approach will make it possible to specify samba private dir
1120 * AND still use NIS+ table. as all domain related data is normally
1121 * stored in org_dir.DOMAIN, this should be ok do do.
1124 pfile = lp_smb_passwd_file();
1125 if( strrchr( pfile, '/') )
1126 pfile = strrchr( pfile, '/') + 1;
1129 * Check if user is already there.
1131 safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
1132 safe_strcat(pfiletmp, ".org_dir",
1133 sizeof(pfiletmp)-strlen(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 nisname = make_nisname_from_name(pdb_get_username(newpwd),
1170 "passwd.org_dir");
1172 result = nisp_get_nis_list(nisname,
1173 MASTER_ONLY|FOLLOW_LINKS|FOLLOW_PATH|\
1174 EXPAND_NAME|HARD_LOOKUP);
1176 if (result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0)
1178 DEBUG(3, ("nis_list failure: %s: %s\n",
1179 nisname, nis_sperrno(result->status)));
1180 nis_freeresult(result);
1182 if (!sys_getpwnam(pdb_get_username(newpwd))) {
1183 /* no such user in system! */
1184 return False;
1187 * user is defined, but not in passwd.org_dir.
1189 local_user = 1;
1190 } else {
1191 safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
1192 safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1);
1193 safe_strcat(pfiletmp, NIS_RES_OBJECT(result)->zo_domain,
1194 sizeof(pfiletmp)-strlen(pfiletmp)-1);
1195 nis_freeresult(result); /* not needed any more */
1197 tblresult = nisp_get_nis_list(pfiletmp,
1198 MASTER_ONLY|FOLLOW_LINKS|\
1199 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
1202 if (local_user || tblresult->status != NIS_SUCCESS)
1205 * no user domain or
1206 * smbpasswd table not found in user domain, fallback to
1207 * default domain.
1209 if (!local_user) /* free previous failed search result */
1210 nis_freeresult(tblresult);
1212 safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
1213 safe_strcat(pfiletmp, ".org_dir",
1214 sizeof(pfiletmp)-strlen(pfiletmp)-1);
1215 tblresult = nis_lookup(pfiletmp, MASTER_ONLY|FOLLOW_LINKS|\
1216 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP);
1217 if (tblresult->status != NIS_SUCCESS)
1219 /* still nothing. bail out */
1220 nis_freeresult(tblresult);
1221 DEBUG(3, ( "nis_lookup failure: %s\n",
1222 nis_sperrno(tblresult->status)));
1223 return False;
1225 /* we need full name for nis_add_entry() */
1226 safe_strcpy(pfiletmp, pfile, sizeof(pfiletmp)-1);
1227 safe_strcat(pfiletmp, ".", sizeof(pfiletmp)-strlen(pfiletmp)-1);
1228 safe_strcat(pfiletmp, NIS_RES_OBJECT(tblresult)->zo_domain,
1229 sizeof(pfiletmp)-strlen(pfiletmp)-1);
1232 memset((char *)&new_obj, 0, sizeof (new_obj));
1233 /* fill entry headers */
1234 /* we do not free these. */
1235 new_obj.zo_name = NIS_RES_OBJECT(tblresult)->zo_name;
1236 new_obj.zo_owner = NIS_RES_OBJECT(tblresult)->zo_owner;
1237 new_obj.zo_group = NIS_RES_OBJECT(tblresult)->zo_group;
1238 new_obj.zo_domain = NIS_RES_OBJECT(tblresult)->zo_domain;
1239 /* uints */
1240 new_obj.zo_access = NIS_RES_OBJECT(tblresult)->zo_access;
1241 new_obj.zo_ttl = NIS_RES_OBJECT(tblresult)->zo_ttl;
1243 new_obj.zo_data.zo_type = ENTRY_OBJ;
1244 new_obj.EN_data.en_type =
1245 NIS_RES_OBJECT(tblresult)->TA_data.ta_type;
1247 ta_maxcol = NIS_RES_OBJECT(tblresult)->TA_data.ta_maxcol;
1249 if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
1250 DEBUG(0, ("memory allocation failure\n"));
1251 nis_freeresult(tblresult);
1252 return False;
1255 memset((char *)ecol, 0, ta_maxcol*sizeof (entry_col));
1256 new_obj.EN_data.en_cols.en_cols_val = ecol;
1257 new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
1259 init_nisp_from_sam(&new_obj, newpwd, NULL);
1261 DEBUG(10, ( "add NIS+ entry: %s\n", nisname));
1262 result = nis_add_entry(pfiletmp, &new_obj, 0);
1264 free(ecol); /* free allocated entry space */
1266 if (result->status != NIS_SUCCESS)
1268 DEBUG(3, ( "NIS+ table update failed: %s\n",
1269 nisname, nis_sperrno(result->status)));
1270 nis_freeresult(tblresult);
1271 nis_freeresult(result);
1272 return False;
1275 nis_freeresult(tblresult);
1276 nis_freeresult(result);
1278 return True;
1281 /************************************************************************
1282 Routine to modify the nisplus passwd entry.
1283 ************************************************************************/
1284 BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override)
1286 nis_result *result, *addresult;
1287 nis_object *obj;
1288 nis_object new_obj;
1289 entry_col *ecol;
1290 int ta_maxcol;
1291 char *pfile = lp_smb_passwd_file();
1292 pstring nisname;
1293 int i;
1295 if (!*pfile)
1297 DEBUG(0, ("no SMB password file set\n"));
1298 return False;
1300 if( strrchr( pfile, '/') )
1301 pfile = strrchr( pfile, '/') + 1;
1303 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.org_dir",
1304 pdb_get_username(newpwd), pfile);
1306 DEBUG(10, ("search by name: %s\n", nisname));
1308 /* Search the table. */
1310 if( !(result = nisp_get_nis_list(nisname, MASTER_ONLY|FOLLOW_LINKS|\
1311 FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP))) {
1312 return False;
1315 if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
1316 /* User not found. */
1317 DEBUG(0,("user not found in NIS+\n"));
1318 nis_freeresult(result);
1319 return False;
1322 obj = NIS_RES_OBJECT(result);
1323 DEBUG(6,("entry found in %s\n", obj->zo_domain));
1325 /* we must create new stub object with EN_MODIFIED flag.
1326 this is because obj from result is going to be freed and
1327 we do not want to break it or cause memory leaks or corruption.
1330 memmove((char *)&new_obj, obj, sizeof (new_obj));
1331 ta_maxcol = obj->TA_data.ta_maxcol;
1333 if(!(ecol = (entry_col*)malloc(ta_maxcol*sizeof(entry_col)))) {
1334 DEBUG(0, ("memory allocation failure\n"));
1335 nis_freeresult(result);
1336 return False;
1339 memmove((char *)ecol, obj->EN_data.en_cols.en_cols_val,
1340 ta_maxcol*sizeof (entry_col));
1341 new_obj.EN_data.en_cols.en_cols_val = ecol;
1342 new_obj.EN_data.en_cols.en_cols_len = ta_maxcol;
1344 if ( init_nisp_from_sam(&new_obj, newpwd, obj) == True ) {
1345 slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s.%s",
1346 pdb_get_username(newpwd), pfile, obj->zo_domain);
1348 DEBUG(10, ("NIS+ table update: %s\n", nisname));
1349 addresult =
1350 nis_modify_entry(nisname, &new_obj,
1351 MOD_SAMEOBJ | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP);
1353 if(addresult->status != NIS_SUCCESS) {
1354 DEBUG(0, ("NIS+ table update failed: %s %s\n",
1355 nisname, nis_sperrno(addresult->status)));
1356 nis_freeresult(addresult);
1357 nis_freeresult(result);
1358 free(ecol);
1359 return False;
1362 DEBUG(6,("password changed\n"));
1363 nis_freeresult(addresult);
1364 } else {
1365 DEBUG(6,("nothing to change!\n"));
1368 free(ecol);
1369 nis_freeresult(result);
1371 return True;
1374 #else
1375 void nisplus_dummy_function(void);
1376 void nisplus_dummy_function(void) { } /* stop some compilers complaining */
1377 #endif /* WITH_NISPLUSSAM */