00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025
00026 #undef DBGC_CLASS
00027 #define DBGC_CLASS DBGC_PASSDB
00028
00029
00030
00031
00032
00033
00034
00035 struct smb_passwd
00036 {
00037 uint32 smb_userid;
00038 const char *smb_name;
00039
00040 const unsigned char *smb_passwd;
00041 const unsigned char *smb_nt_passwd;
00042
00043 uint16 acct_ctrl;
00044 time_t pass_last_set_time;
00045 };
00046
00047 struct smbpasswd_privates
00048 {
00049
00050 int pw_file_lock_depth;
00051
00052
00053 FILE *pw_file;
00054
00055
00056 struct smb_passwd pw_buf;
00057 pstring user_name;
00058 unsigned char smbpwd[16];
00059 unsigned char smbntpwd[16];
00060
00061
00062 const char *smbpasswd_file;
00063 };
00064
00065 enum pwf_access_type { PWF_READ, PWF_UPDATE, PWF_CREATE };
00066
00067 static SIG_ATOMIC_T gotalarm;
00068
00069
00070
00071
00072
00073 static void gotalarm_sig(void)
00074 {
00075 gotalarm = 1;
00076 }
00077
00078
00079
00080
00081
00082
00083 static BOOL do_file_lock(int fd, int waitsecs, int type)
00084 {
00085 SMB_STRUCT_FLOCK lock;
00086 int ret;
00087 void (*oldsig_handler)(int);
00088
00089 gotalarm = 0;
00090 oldsig_handler = CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
00091
00092 lock.l_type = type;
00093 lock.l_whence = SEEK_SET;
00094 lock.l_start = 0;
00095 lock.l_len = 1;
00096 lock.l_pid = 0;
00097
00098 alarm(waitsecs);
00099
00100 ret = fcntl(fd, SMB_F_SETLKW, &lock);
00101 alarm(0);
00102 CatchSignal(SIGALRM, SIGNAL_CAST oldsig_handler);
00103
00104 if (gotalarm) {
00105 DEBUG(0, ("do_file_lock: failed to %s file.\n",
00106 type == F_UNLCK ? "unlock" : "lock"));
00107 return False;
00108 }
00109
00110 return (ret == 0);
00111 }
00112
00113
00114
00115
00116
00117 static BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth)
00118 {
00119 if (fd < 0) {
00120 return False;
00121 }
00122
00123 if(*plock_depth == 0) {
00124 if (!do_file_lock(fd, secs, type)) {
00125 DEBUG(10,("pw_file_lock: locking file failed, error = %s.\n",
00126 strerror(errno)));
00127 return False;
00128 }
00129 }
00130
00131 (*plock_depth)++;
00132
00133 return True;
00134 }
00135
00136
00137
00138
00139
00140 static BOOL pw_file_unlock(int fd, int *plock_depth)
00141 {
00142 BOOL ret=True;
00143
00144 if (fd == 0 || *plock_depth == 0) {
00145 return True;
00146 }
00147
00148 if(*plock_depth == 1) {
00149 ret = do_file_lock(fd, 5, F_UNLCK);
00150 }
00151
00152 if (*plock_depth > 0) {
00153 (*plock_depth)--;
00154 }
00155
00156 if(!ret) {
00157 DEBUG(10,("pw_file_unlock: unlocking file failed, error = %s.\n",
00158 strerror(errno)));
00159 }
00160 return ret;
00161 }
00162
00163
00164
00165
00166
00167 static void pdb_init_smb(struct smb_passwd *user)
00168 {
00169 if (user == NULL)
00170 return;
00171 ZERO_STRUCTP (user);
00172
00173 user->pass_last_set_time = (time_t)0;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183 static FILE *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int *lock_depth)
00184 {
00185 FILE *fp = NULL;
00186 const char *open_mode = NULL;
00187 int race_loop = 0;
00188 int lock_type = F_RDLCK;
00189
00190 if (!*pfile) {
00191 DEBUG(0, ("startsmbfilepwent: No SMB password file set\n"));
00192 return (NULL);
00193 }
00194
00195 switch(type) {
00196 case PWF_READ:
00197 open_mode = "rb";
00198 lock_type = F_RDLCK;
00199 break;
00200 case PWF_UPDATE:
00201 open_mode = "r+b";
00202 lock_type = F_WRLCK;
00203 break;
00204 case PWF_CREATE:
00205
00206
00207
00208 {
00209 int i, fd = -1;
00210
00211 for(i = 0; i < 5; i++) {
00212 if((fd = sys_open(pfile, O_CREAT|O_TRUNC|O_EXCL|O_RDWR, 0600))!=-1) {
00213 break;
00214 }
00215 sys_usleep(200);
00216 }
00217 if(fd == -1) {
00218 DEBUG(0,("startsmbfilepwent_internal: too many race conditions \
00219 creating file %s\n", pfile));
00220 return NULL;
00221 }
00222 close(fd);
00223 open_mode = "r+b";
00224 lock_type = F_WRLCK;
00225 break;
00226 }
00227 }
00228
00229 for(race_loop = 0; race_loop < 5; race_loop++) {
00230 DEBUG(10, ("startsmbfilepwent_internal: opening file %s\n", pfile));
00231
00232 if((fp = sys_fopen(pfile, open_mode)) == NULL) {
00233
00234
00235
00236
00237
00238 if (errno == ENOENT) {
00239 if ((fp = sys_fopen(pfile, "a+")) != NULL) {
00240 DEBUG(0, ("startsmbfilepwent_internal: file %s did not \
00241 exist. File successfully created.\n", pfile));
00242 } else {
00243 DEBUG(0, ("startsmbfilepwent_internal: file %s did not \
00244 exist. Couldn't create new one. Error was: %s",
00245 pfile, strerror(errno)));
00246 return NULL;
00247 }
00248 } else {
00249 DEBUG(0, ("startsmbfilepwent_internal: unable to open file %s. \
00250 Error was: %s\n", pfile, strerror(errno)));
00251 return NULL;
00252 }
00253 }
00254
00255 if (!pw_file_lock(fileno(fp), lock_type, 5, lock_depth)) {
00256 DEBUG(0, ("startsmbfilepwent_internal: unable to lock file %s. \
00257 Error was %s\n", pfile, strerror(errno) ));
00258 fclose(fp);
00259 return NULL;
00260 }
00261
00262
00263
00264
00265
00266
00267 if(type == PWF_READ) {
00268 break;
00269 } else {
00270 SMB_STRUCT_STAT sbuf1, sbuf2;
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 if (sys_stat(pfile,&sbuf1) != 0) {
00281 DEBUG(0, ("startsmbfilepwent_internal: unable to stat file %s. \
00282 Error was %s\n", pfile, strerror(errno)));
00283 pw_file_unlock(fileno(fp), lock_depth);
00284 fclose(fp);
00285 return NULL;
00286 }
00287
00288 if (sys_fstat(fileno(fp),&sbuf2) != 0) {
00289 DEBUG(0, ("startsmbfilepwent_internal: unable to fstat file %s. \
00290 Error was %s\n", pfile, strerror(errno)));
00291 pw_file_unlock(fileno(fp), lock_depth);
00292 fclose(fp);
00293 return NULL;
00294 }
00295
00296 if( sbuf1.st_ino == sbuf2.st_ino) {
00297
00298 break;
00299 }
00300
00301
00302
00303
00304
00305 pw_file_unlock(fileno(fp), lock_depth);
00306 fclose(fp);
00307 }
00308 }
00309
00310 if(race_loop == 5) {
00311 DEBUG(0, ("startsmbfilepwent_internal: too many race conditions opening file %s\n", pfile));
00312 return NULL;
00313 }
00314
00315
00316 setvbuf(fp, (char *)NULL, _IOFBF, 1024);
00317
00318
00319 #ifdef HAVE_FCHMOD
00320 if(fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1) {
00321 #else
00322 if(chmod(pfile, S_IRUSR|S_IWUSR) == -1) {
00323 #endif
00324 DEBUG(0, ("startsmbfilepwent_internal: failed to set 0600 permissions on password file %s. \
00325 Error was %s\n.", pfile, strerror(errno) ));
00326 pw_file_unlock(fileno(fp), lock_depth);
00327 fclose(fp);
00328 return NULL;
00329 }
00330
00331
00332 return fp;
00333 }
00334
00335
00336
00337
00338
00339 static void endsmbfilepwent(FILE *fp, int *lock_depth)
00340 {
00341 if (!fp) {
00342 return;
00343 }
00344
00345 pw_file_unlock(fileno(fp), lock_depth);
00346 fclose(fp);
00347 DEBUG(7, ("endsmbfilepwent_internal: closed password file.\n"));
00348 }
00349
00350
00351
00352
00353
00354 static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_state, FILE *fp)
00355 {
00356
00357 struct smb_passwd *pw_buf = &smbpasswd_state->pw_buf;
00358 char *user_name = smbpasswd_state->user_name;
00359 unsigned char *smbpwd = smbpasswd_state->smbpwd;
00360 unsigned char *smbntpwd = smbpasswd_state->smbntpwd;
00361 char linebuf[256];
00362 int c;
00363 unsigned char *p;
00364 long uidval;
00365 size_t linebuf_len;
00366 char *status;
00367
00368 if(fp == NULL) {
00369 DEBUG(0,("getsmbfilepwent: Bad password file pointer.\n"));
00370 return NULL;
00371 }
00372
00373 pdb_init_smb(pw_buf);
00374 pw_buf->acct_ctrl = ACB_NORMAL;
00375
00376
00377
00378
00379 status = linebuf;
00380 while (status && !feof(fp)) {
00381 linebuf[0] = '\0';
00382
00383 status = fgets(linebuf, 256, fp);
00384 if (status == NULL && ferror(fp)) {
00385 return NULL;
00386 }
00387
00388
00389
00390
00391
00392 if ((linebuf_len = strlen(linebuf)) == 0) {
00393 continue;
00394 }
00395
00396 if (linebuf[linebuf_len - 1] != '\n') {
00397 c = '\0';
00398 while (!ferror(fp) && !feof(fp)) {
00399 c = fgetc(fp);
00400 if (c == '\n') {
00401 break;
00402 }
00403 }
00404 } else {
00405 linebuf[linebuf_len - 1] = '\0';
00406 }
00407
00408 #ifdef DEBUG_PASSWORD
00409 DEBUG(100, ("getsmbfilepwent: got line |%s|\n", linebuf));
00410 #endif
00411 if ((linebuf[0] == 0) && feof(fp)) {
00412 DEBUG(4, ("getsmbfilepwent: end of file reached\n"));
00413 break;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 if (linebuf[0] == '#' || linebuf[0] == '\0') {
00432 DEBUG(6, ("getsmbfilepwent: skipping comment or blank line\n"));
00433 continue;
00434 }
00435 p = (unsigned char *) strchr_m(linebuf, ':');
00436 if (p == NULL) {
00437 DEBUG(0, ("getsmbfilepwent: malformed password entry (no :)\n"));
00438 continue;
00439 }
00440
00441
00442
00443
00444
00445 SMB_ASSERT(sizeof(pstring) > sizeof(linebuf));
00446
00447 strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
00448 user_name[PTR_DIFF(p, linebuf)] = '\0';
00449
00450
00451
00452 p++;
00453
00454 if(*p == '-') {
00455 DEBUG(0, ("getsmbfilepwent: user name %s has a negative uid.\n", user_name));
00456 continue;
00457 }
00458
00459 if (!isdigit(*p)) {
00460 DEBUG(0, ("getsmbfilepwent: malformed password entry for user %s (uid not number)\n",
00461 user_name));
00462 continue;
00463 }
00464
00465 uidval = atoi((char *) p);
00466
00467 while (*p && isdigit(*p)) {
00468 p++;
00469 }
00470
00471 if (*p != ':') {
00472 DEBUG(0, ("getsmbfilepwent: malformed password entry for user %s (no : after uid)\n",
00473 user_name));
00474 continue;
00475 }
00476
00477 pw_buf->smb_name = user_name;
00478 pw_buf->smb_userid = uidval;
00479
00480
00481
00482
00483
00484
00485
00486
00487 p++;
00488
00489 if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
00490 DEBUG(0, ("getsmbfilepwent: malformed password entry for user %s (passwd too short)\n",
00491 user_name ));
00492 continue;
00493 }
00494
00495 if (p[32] != ':') {
00496 DEBUG(0, ("getsmbfilepwent: malformed password entry for user %s (no terminating :)\n",
00497 user_name));
00498 continue;
00499 }
00500
00501 if (strnequal((char *) p, "NO PASSWORD", 11)) {
00502 pw_buf->smb_passwd = NULL;
00503 pw_buf->acct_ctrl |= ACB_PWNOTREQ;
00504 } else {
00505 if (*p == '*' || *p == 'X') {
00506
00507 pw_buf->smb_passwd = NULL;
00508 DEBUG(10, ("getsmbfilepwent: LM password for user %s invalidated\n", user_name));
00509 } else if (pdb_gethexpwd((char *)p, smbpwd)) {
00510 pw_buf->smb_passwd = smbpwd;
00511 } else {
00512 pw_buf->smb_passwd = NULL;
00513 DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry for user %s \
00514 (non hex chars)\n", user_name));
00515 }
00516 }
00517
00518
00519
00520
00521
00522 pw_buf->smb_nt_passwd = NULL;
00523 p += 33;
00524 if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
00525 if (*p != '*' && *p != 'X') {
00526 if(pdb_gethexpwd((char *)p,smbntpwd)) {
00527 pw_buf->smb_nt_passwd = smbntpwd;
00528 }
00529 }
00530 p += 33;
00531 }
00532
00533 DEBUG(5,("getsmbfilepwent: returning passwd entry for user %s, uid %ld\n",
00534 user_name, uidval));
00535
00536 if (*p == '[') {
00537 unsigned char *end_p = (unsigned char *)strchr_m((char *)p, ']');
00538 pw_buf->acct_ctrl = pdb_decode_acct_ctrl((char*)p);
00539
00540
00541 if(pw_buf->acct_ctrl == 0) {
00542 pw_buf->acct_ctrl = ACB_NORMAL;
00543 }
00544
00545
00546 if(end_p) {
00547 p = end_p + 1;
00548 }
00549 if(*p == ':') {
00550 p++;
00551 if(*p && (StrnCaseCmp((char *)p, "LCT-", 4)==0)) {
00552 int i;
00553 p += 4;
00554 for(i = 0; i < 8; i++) {
00555 if(p[i] == '\0' || !isxdigit(p[i])) {
00556 break;
00557 }
00558 }
00559 if(i == 8) {
00560
00561
00562
00563
00564
00565 pw_buf->pass_last_set_time = (time_t)strtol((char *)p, NULL, 16);
00566 }
00567 }
00568 }
00569 } else {
00570
00571
00572
00573
00574
00575
00576 if(pw_buf->smb_name[strlen(pw_buf->smb_name) - 1] == '$') {
00577 pw_buf->acct_ctrl &= ~ACB_NORMAL;
00578 pw_buf->acct_ctrl |= ACB_WSTRUST;
00579 }
00580 }
00581
00582 return pw_buf;
00583 }
00584
00585 DEBUG(5,("getsmbfilepwent: end of file reached.\n"));
00586 return NULL;
00587 }
00588
00589
00590
00591
00592
00593 static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd)
00594 {
00595 int new_entry_length;
00596 char *new_entry;
00597 char *p;
00598
00599 new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 +
00600 NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2;
00601
00602 if((new_entry = (char *)SMB_MALLOC( new_entry_length )) == NULL) {
00603 DEBUG(0, ("format_new_smbpasswd_entry: Malloc failed adding entry for user %s.\n",
00604 newpwd->smb_name ));
00605 return NULL;
00606 }
00607
00608 slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->smb_name, (unsigned)newpwd->smb_userid);
00609
00610 p = new_entry+strlen(new_entry);
00611 pdb_sethexpwd(p, newpwd->smb_passwd, newpwd->acct_ctrl);
00612 p+=strlen(p);
00613 *p = ':';
00614 p++;
00615
00616 pdb_sethexpwd(p, newpwd->smb_nt_passwd, newpwd->acct_ctrl);
00617 p+=strlen(p);
00618 *p = ':';
00619 p++;
00620
00621
00622 slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n",
00623 pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN),
00624 (uint32)newpwd->pass_last_set_time);
00625
00626 return new_entry;
00627 }
00628
00629
00630
00631
00632
00633 static NTSTATUS add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state,
00634 struct smb_passwd *newpwd)
00635 {
00636 const char *pfile = smbpasswd_state->smbpasswd_file;
00637 struct smb_passwd *pwd = NULL;
00638 FILE *fp = NULL;
00639 int wr_len;
00640 int fd;
00641 size_t new_entry_length;
00642 char *new_entry;
00643 SMB_OFF_T offpos;
00644
00645
00646 fp = startsmbfilepwent(pfile, PWF_UPDATE, &smbpasswd_state->pw_file_lock_depth);
00647
00648 if (fp == NULL && errno == ENOENT) {
00649
00650 fp = startsmbfilepwent(pfile, PWF_CREATE, &smbpasswd_state->pw_file_lock_depth);
00651 }
00652
00653 if (fp == NULL) {
00654 DEBUG(0, ("add_smbfilepwd_entry: unable to open file.\n"));
00655 return map_nt_error_from_unix(errno);
00656 }
00657
00658
00659
00660
00661
00662 while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL) {
00663 if (strequal(newpwd->smb_name, pwd->smb_name)) {
00664 DEBUG(0, ("add_smbfilepwd_entry: entry with name %s already exists\n", pwd->smb_name));
00665 endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
00666 return NT_STATUS_USER_EXISTS;
00667 }
00668 }
00669
00670
00671
00672
00673
00674
00675
00676
00677 fd = fileno(fp);
00678
00679 if((offpos = sys_lseek(fd, 0, SEEK_END)) == -1) {
00680 NTSTATUS result = map_nt_error_from_unix(errno);
00681 DEBUG(0, ("add_smbfilepwd_entry(sys_lseek): Failed to add entry for user %s to file %s. \
00682 Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
00683 endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
00684 return result;
00685 }
00686
00687 if((new_entry = format_new_smbpasswd_entry(newpwd)) == NULL) {
00688 DEBUG(0, ("add_smbfilepwd_entry(malloc): Failed to add entry for user %s to file %s. \
00689 Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
00690 endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
00691 return NT_STATUS_NO_MEMORY;
00692 }
00693
00694 new_entry_length = strlen(new_entry);
00695
00696 #ifdef DEBUG_PASSWORD
00697 DEBUG(100, ("add_smbfilepwd_entry(%d): new_entry_len %d made line |%s|",
00698 fd, (int)new_entry_length, new_entry));
00699 #endif
00700
00701 if ((wr_len = write(fd, new_entry, new_entry_length)) != new_entry_length) {
00702 NTSTATUS result = map_nt_error_from_unix(errno);
00703 DEBUG(0, ("add_smbfilepwd_entry(write): %d Failed to add entry for user %s to file %s. \
00704 Error was %s\n", wr_len, newpwd->smb_name, pfile, strerror(errno)));
00705
00706
00707 if(sys_ftruncate(fd, offpos) == -1) {
00708 DEBUG(0, ("add_smbfilepwd_entry: ERROR failed to ftruncate file %s. \
00709 Error was %s. Password file may be corrupt ! Please examine by hand !\n",
00710 newpwd->smb_name, strerror(errno)));
00711 }
00712
00713 endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
00714 free(new_entry);
00715 return result;
00716 }
00717
00718 free(new_entry);
00719 endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
00720 return NT_STATUS_OK;
00721 }
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732 static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const struct smb_passwd* pwd)
00733 {
00734
00735 pstring user_name;
00736
00737 char *status;
00738 char linebuf[256];
00739 char readbuf[1024];
00740 int c;
00741 fstring ascii_p16;
00742 fstring encode_bits;
00743 unsigned char *p = NULL;
00744 size_t linebuf_len = 0;
00745 FILE *fp;
00746 int lockfd;
00747 const char *pfile = smbpasswd_state->smbpasswd_file;
00748 BOOL found_entry = False;
00749 BOOL got_pass_last_set_time = False;
00750
00751 SMB_OFF_T pwd_seekpos = 0;
00752
00753 int i;
00754 int wr_len;
00755 int fd;
00756
00757 if (!*pfile) {
00758 DEBUG(0, ("No SMB password file set\n"));
00759 return False;
00760 }
00761 DEBUG(10, ("mod_smbfilepwd_entry: opening file %s\n", pfile));
00762
00763 fp = sys_fopen(pfile, "r+");
00764
00765 if (fp == NULL) {
00766 DEBUG(0, ("mod_smbfilepwd_entry: unable to open file %s\n", pfile));
00767 return False;
00768 }
00769
00770 setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
00771
00772 lockfd = fileno(fp);
00773
00774 if (!pw_file_lock(lockfd, F_WRLCK, 5, &smbpasswd_state->pw_file_lock_depth)) {
00775 DEBUG(0, ("mod_smbfilepwd_entry: unable to lock file %s\n", pfile));
00776 fclose(fp);
00777 return False;
00778 }
00779
00780
00781 chmod(pfile, 0600);
00782
00783
00784
00785
00786
00787 status = linebuf;
00788 while (status && !feof(fp)) {
00789 pwd_seekpos = sys_ftell(fp);
00790
00791 linebuf[0] = '\0';
00792
00793 status = fgets(linebuf, sizeof(linebuf), fp);
00794 if (status == NULL && ferror(fp)) {
00795 pw_file_unlock(lockfd, &smbpasswd_state->pw_file_lock_depth);
00796 fclose(fp);
00797 return False;
00798 }
00799
00800
00801
00802
00803
00804 linebuf_len = strlen(linebuf);
00805 if (linebuf[linebuf_len - 1] != '\n') {
00806 c = '\0';
00807 while (!ferror(fp) && !feof(fp)) {
00808 c = fgetc(fp);
00809 if (c == '\n') {
00810 break;
00811 }
00812 }
00813 } else {
00814 linebuf[linebuf_len - 1] = '\0';
00815 }
00816
00817 #ifdef DEBUG_PASSWORD
00818 DEBUG(100, ("mod_smbfilepwd_entry: got line |%s|\n", linebuf));
00819 #endif
00820
00821 if ((linebuf[0] == 0) && feof(fp)) {
00822 DEBUG(4, ("mod_smbfilepwd_entry: end of file reached\n"));
00823 break;
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 if (linebuf[0] == '#' || linebuf[0] == '\0') {
00840 DEBUG(6, ("mod_smbfilepwd_entry: skipping comment or blank line\n"));
00841 continue;
00842 }
00843
00844 p = (unsigned char *) strchr_m(linebuf, ':');
00845
00846 if (p == NULL) {
00847 DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no :)\n"));
00848 continue;
00849 }
00850
00851
00852
00853
00854
00855
00856 SMB_ASSERT(sizeof(user_name) > sizeof(linebuf));
00857
00858 strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
00859 user_name[PTR_DIFF(p, linebuf)] = '\0';
00860 if (strequal(user_name, pwd->smb_name)) {
00861 found_entry = True;
00862 break;
00863 }
00864 }
00865
00866 if (!found_entry) {
00867 pw_file_unlock(lockfd, &smbpasswd_state->pw_file_lock_depth);
00868 fclose(fp);
00869
00870 DEBUG(2, ("Cannot update entry for user %s, as they don't exist in the smbpasswd file!\n",
00871 pwd->smb_name));
00872 return False;
00873 }
00874
00875 DEBUG(6, ("mod_smbfilepwd_entry: entry exists for user %s\n", pwd->smb_name));
00876
00877
00878 p++;
00879
00880 if (!isdigit(*p)) {
00881 DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry for user %s (uid not number)\n",
00882 pwd->smb_name));
00883 pw_file_unlock(lockfd, &smbpasswd_state->pw_file_lock_depth);
00884 fclose(fp);
00885 return False;
00886 }
00887
00888 while (*p && isdigit(*p)) {
00889 p++;
00890 }
00891 if (*p != ':') {
00892 DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry for user %s (no : after uid)\n",
00893 pwd->smb_name));
00894 pw_file_unlock(lockfd, &smbpasswd_state->pw_file_lock_depth);
00895 fclose(fp);
00896 return False;
00897 }
00898
00899
00900
00901
00902
00903
00904 p++;
00905
00906
00907 pwd_seekpos += PTR_DIFF(p, linebuf);
00908
00909 if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
00910 DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry for user %s (passwd too short)\n",
00911 pwd->smb_name));
00912 pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);
00913 fclose(fp);
00914 return (False);
00915 }
00916
00917 if (p[32] != ':') {
00918 DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry for user %s (no terminating :)\n",
00919 pwd->smb_name));
00920 pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);
00921 fclose(fp);
00922 return False;
00923 }
00924
00925
00926 p += 33;
00927 if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
00928 DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry for user %s (passwd too short)\n",
00929 pwd->smb_name));
00930 pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);
00931 fclose(fp);
00932 return (False);
00933 }
00934
00935 if (p[32] != ':') {
00936 DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry for user %s (no terminating :)\n",
00937 pwd->smb_name));
00938 pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);
00939 fclose(fp);
00940 return False;
00941 }
00942
00943
00944
00945
00946
00947 p += 33;
00948
00949 if (*p == '[') {
00950 i = 0;
00951 encode_bits[i++] = *p++;
00952 while((linebuf_len > PTR_DIFF(p, linebuf)) && (*p != ']')) {
00953 encode_bits[i++] = *p++;
00954 }
00955
00956 encode_bits[i++] = ']';
00957 encode_bits[i++] = '\0';
00958
00959 if(i == NEW_PW_FORMAT_SPACE_PADDED_LEN) {
00960
00961
00962
00963
00964
00965 fstrcpy(encode_bits, pdb_encode_acct_ctrl(pwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));
00966 } else {
00967 DEBUG(0,("mod_smbfilepwd_entry: Using old smbpasswd format for user %s. \
00968 This is no longer supported.!\n", pwd->smb_name));
00969 DEBUG(0,("mod_smbfilepwd_entry: No changes made, failing.!\n"));
00970 pw_file_unlock(lockfd, &smbpasswd_state->pw_file_lock_depth);
00971 fclose(fp);
00972 return False;
00973 }
00974
00975
00976 if(linebuf_len > PTR_DIFF(p, linebuf)) {
00977 p++;
00978 }
00979
00980 if((linebuf_len > PTR_DIFF(p, linebuf)) && (*p == ':')) {
00981 p++;
00982
00983
00984 if((linebuf_len > (PTR_DIFF(p, linebuf) + 13)) && (StrnCaseCmp((char *)p, "LCT-", 4) == 0)) {
00985 p += 4;
00986 for(i = 0; i < 8; i++) {
00987 if(p[i] == '\0' || !isxdigit(p[i])) {
00988 break;
00989 }
00990 }
00991 if(i == 8) {
00992
00993
00994
00995
00996
00997 got_pass_last_set_time = True;
00998 }
00999 }
01000 }
01001 }
01002
01003
01004
01005
01006 pdb_sethexpwd(ascii_p16, pwd->smb_passwd, pwd->acct_ctrl);
01007
01008
01009 ascii_p16[32] = ':';
01010 wr_len = 66;
01011 pdb_sethexpwd(ascii_p16+33, pwd->smb_nt_passwd, pwd->acct_ctrl);
01012 ascii_p16[65] = ':';
01013 ascii_p16[66] = '\0';
01014
01015
01016 if(got_pass_last_set_time) {
01017 slprintf(&ascii_p16[strlen(ascii_p16)],
01018 sizeof(ascii_p16)-(strlen(ascii_p16)+1),
01019 "%s:LCT-%08X:",
01020 encode_bits, (uint32)pwd->pass_last_set_time );
01021 wr_len = strlen(ascii_p16);
01022 }
01023
01024 #ifdef DEBUG_PASSWORD
01025 DEBUG(100,("mod_smbfilepwd_entry: "));
01026 dump_data(100, ascii_p16, wr_len);
01027 #endif
01028
01029 if(wr_len > sizeof(linebuf)) {
01030 DEBUG(0, ("mod_smbfilepwd_entry: line to write (%d) is too long.\n", wr_len+1));
01031 pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);
01032 fclose(fp);
01033 return (False);
01034 }
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045 fd = fileno(fp);
01046
01047 if (sys_lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) {
01048 DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
01049 pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);
01050 fclose(fp);
01051 return False;
01052 }
01053
01054
01055 if (read(fd, linebuf, wr_len+1) != wr_len+1) {
01056 DEBUG(0, ("mod_smbfilepwd_entry: read fail on file %s.\n", pfile));
01057 pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);
01058 fclose(fp);
01059 return False;
01060 }
01061
01062 if ((linebuf[0] != ':') || (linebuf[wr_len] != ':')) {
01063 DEBUG(0, ("mod_smbfilepwd_entry: check on passwd file %s failed.\n", pfile));
01064 pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);
01065 fclose(fp);
01066 return False;
01067 }
01068
01069 if (sys_lseek(fd, pwd_seekpos, SEEK_SET) != pwd_seekpos) {
01070 DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
01071 pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);
01072 fclose(fp);
01073 return False;
01074 }
01075
01076 if (write(fd, ascii_p16, wr_len) != wr_len) {
01077 DEBUG(0, ("mod_smbfilepwd_entry: write failed in passwd file %s\n", pfile));
01078 pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);
01079 fclose(fp);
01080 return False;
01081 }
01082
01083 pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);
01084 fclose(fp);
01085 return True;
01086 }
01087
01088
01089
01090
01091
01092 static BOOL del_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const char *name)
01093 {
01094 const char *pfile = smbpasswd_state->smbpasswd_file;
01095 pstring pfile2;
01096 struct smb_passwd *pwd = NULL;
01097 FILE *fp = NULL;
01098 FILE *fp_write = NULL;
01099 int pfile2_lockdepth = 0;
01100
01101 slprintf(pfile2, sizeof(pfile2)-1, "%s.%u", pfile, (unsigned)sys_getpid() );
01102
01103
01104
01105
01106
01107
01108
01109 if((fp = startsmbfilepwent(pfile, PWF_UPDATE, &smbpasswd_state->pw_file_lock_depth)) == NULL) {
01110 DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile));
01111 return False;
01112 }
01113
01114
01115
01116
01117 if((fp_write = startsmbfilepwent(pfile2, PWF_CREATE, &pfile2_lockdepth)) == NULL) {
01118 DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile));
01119 endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
01120 return False;
01121 }
01122
01123
01124
01125
01126
01127 while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL) {
01128 char *new_entry;
01129 size_t new_entry_length;
01130
01131 if (strequal(name, pwd->smb_name)) {
01132 DEBUG(10, ("del_smbfilepwd_entry: found entry with "
01133 "name %s - deleting it.\n", name));
01134 continue;
01135 }
01136
01137
01138
01139
01140
01141 if((new_entry = format_new_smbpasswd_entry(pwd)) == NULL) {
01142 DEBUG(0, ("del_smbfilepwd_entry(malloc): Failed to copy entry for user %s to file %s. \
01143 Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
01144 unlink(pfile2);
01145 endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
01146 endsmbfilepwent(fp_write, &pfile2_lockdepth);
01147 return False;
01148 }
01149
01150 new_entry_length = strlen(new_entry);
01151
01152 if(fwrite(new_entry, 1, new_entry_length, fp_write) != new_entry_length) {
01153 DEBUG(0, ("del_smbfilepwd_entry(write): Failed to copy entry for user %s to file %s. \
01154 Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
01155 unlink(pfile2);
01156 endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
01157 endsmbfilepwent(fp_write, &pfile2_lockdepth);
01158 free(new_entry);
01159 return False;
01160 }
01161
01162 free(new_entry);
01163 }
01164
01165
01166
01167
01168
01169 if(fflush(fp_write) != 0) {
01170 DEBUG(0, ("del_smbfilepwd_entry: Failed to flush file %s. Error was %s\n", pfile2, strerror(errno)));
01171 endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
01172 endsmbfilepwent(fp_write,&pfile2_lockdepth);
01173 return False;
01174 }
01175
01176
01177
01178
01179
01180 if(rename(pfile2,pfile) != 0) {
01181 unlink(pfile2);
01182 }
01183
01184 endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
01185 endsmbfilepwent(fp_write,&pfile2_lockdepth);
01186 return True;
01187 }
01188
01189
01190
01191
01192
01193
01194
01195 static BOOL build_smb_pass (struct smb_passwd *smb_pw, const struct samu *sampass)
01196 {
01197 uint32 rid;
01198
01199 if (sampass == NULL)
01200 return False;
01201 ZERO_STRUCTP(smb_pw);
01202
01203 if (!IS_SAM_DEFAULT(sampass, PDB_USERSID)) {
01204 rid = pdb_get_user_rid(sampass);
01205
01206
01207 if (rid == DOMAIN_USER_RID_GUEST) {
01208 struct passwd *passwd = getpwnam_alloc(NULL, lp_guestaccount());
01209 if (!passwd) {
01210 DEBUG(0, ("Could not find guest account via getpwnam()! (%s)\n", lp_guestaccount()));
01211 return False;
01212 }
01213 smb_pw->smb_userid=passwd->pw_uid;
01214 TALLOC_FREE(passwd);
01215 } else if (algorithmic_pdb_rid_is_user(rid)) {
01216 smb_pw->smb_userid=algorithmic_pdb_user_rid_to_uid(rid);
01217 } else {
01218 DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));
01219 return False;
01220 }
01221 }
01222
01223 smb_pw->smb_name=(const char*)pdb_get_username(sampass);
01224
01225 smb_pw->smb_passwd=pdb_get_lanman_passwd(sampass);
01226 smb_pw->smb_nt_passwd=pdb_get_nt_passwd(sampass);
01227
01228 smb_pw->acct_ctrl=pdb_get_acct_ctrl(sampass);
01229 smb_pw->pass_last_set_time=pdb_get_pass_last_set_time(sampass);
01230
01231 return True;
01232 }
01233
01234
01235
01236
01237
01238 static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
01239 struct samu *sam_pass, const struct smb_passwd *pw_buf)
01240 {
01241 struct passwd *pwfile;
01242
01243 if ( !sam_pass ) {
01244 DEBUG(5,("build_sam_account: struct samu is NULL\n"));
01245 return False;
01246 }
01247
01248
01249
01250 if ( !(pwfile = Get_Pwnam_alloc(NULL, pw_buf->smb_name )) ) {
01251 DEBUG(0,("build_sam_account: smbpasswd database is corrupt! username %s with uid "
01252 "%u is not in unix passwd database!\n", pw_buf->smb_name, pw_buf->smb_userid));
01253 return False;
01254 }
01255
01256 if ( !NT_STATUS_IS_OK( samu_set_unix(sam_pass, pwfile )) )
01257 return False;
01258
01259 TALLOC_FREE(pwfile);
01260
01261
01262
01263 pdb_set_nt_passwd (sam_pass, pw_buf->smb_nt_passwd, PDB_SET);
01264 pdb_set_lanman_passwd (sam_pass, pw_buf->smb_passwd, PDB_SET);
01265 pdb_set_acct_ctrl (sam_pass, pw_buf->acct_ctrl, PDB_SET);
01266 pdb_set_pass_last_set_time (sam_pass, pw_buf->pass_last_set_time, PDB_SET);
01267 pdb_set_pass_can_change_time (sam_pass, pw_buf->pass_last_set_time, PDB_SET);
01268
01269 return True;
01270 }
01271
01272
01273
01274
01275
01276 static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update, uint32 acb_mask)
01277 {
01278 struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
01279
01280 smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file,
01281 update ? PWF_UPDATE : PWF_READ,
01282 &(smbpasswd_state->pw_file_lock_depth));
01283
01284
01285 if (!smbpasswd_state->pw_file && update && errno == ENOENT) {
01286 FILE *fp;
01287
01288
01289 DEBUG(0,("smbpasswd file did not exist - attempting to create it.\n"));
01290 fp = sys_fopen(smbpasswd_state->smbpasswd_file, "w");
01291 if (fp) {
01292 fprintf(fp, "# Samba SMB password file\n");
01293 fclose(fp);
01294 }
01295
01296 smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file,
01297 update ? PWF_UPDATE : PWF_READ,
01298 &(smbpasswd_state->pw_file_lock_depth));
01299 }
01300
01301 if (smbpasswd_state->pw_file != NULL)
01302 return NT_STATUS_OK;
01303 else
01304 return NT_STATUS_UNSUCCESSFUL;
01305 }
01306
01307 static void smbpasswd_endsampwent (struct pdb_methods *my_methods)
01308 {
01309 struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
01310 endsmbfilepwent(smbpasswd_state->pw_file, &(smbpasswd_state->pw_file_lock_depth));
01311 }
01312
01313
01314
01315
01316 static NTSTATUS smbpasswd_getsampwent(struct pdb_methods *my_methods, struct samu *user)
01317 {
01318 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
01319 struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
01320 struct smb_passwd *pw_buf=NULL;
01321 BOOL done = False;
01322
01323 DEBUG(5,("pdb_getsampwent\n"));
01324
01325 if ( !user ) {
01326 DEBUG(5,("pdb_getsampwent (smbpasswd): user is NULL\n"));
01327 return nt_status;
01328 }
01329
01330 while (!done) {
01331
01332 pw_buf = getsmbfilepwent(smbpasswd_state, smbpasswd_state->pw_file);
01333 if (pw_buf == NULL)
01334 return nt_status;
01335
01336
01337
01338
01339 if (build_sam_account(smbpasswd_state, user, pw_buf))
01340 done = True;
01341 }
01342
01343 DEBUG(5,("getsampwent (smbpasswd): done\n"));
01344
01345
01346 return NT_STATUS_OK;
01347 }
01348
01349
01350
01351
01352
01353
01354
01355 static NTSTATUS smbpasswd_getsampwnam(struct pdb_methods *my_methods,
01356 struct samu *sam_acct, const char *username)
01357 {
01358 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
01359 struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
01360 struct smb_passwd *smb_pw;
01361 FILE *fp = NULL;
01362
01363 DEBUG(10, ("getsampwnam (smbpasswd): search by name: %s\n", username));
01364
01365
01366
01367
01368 fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ, &(smbpasswd_state->pw_file_lock_depth));
01369
01370 if (fp == NULL) {
01371 DEBUG(0, ("Unable to open passdb database.\n"));
01372 return nt_status;
01373 }
01374
01375 while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL)&& (!strequal(smb_pw->smb_name, username)) )
01376 ;
01377
01378 endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
01379
01380
01381
01382 if (smb_pw == NULL)
01383 return nt_status;
01384
01385 DEBUG(10, ("getsampwnam (smbpasswd): found by name: %s\n", smb_pw->smb_name));
01386
01387 if (!sam_acct) {
01388 DEBUG(10,("getsampwnam (smbpasswd): struct samu is NULL\n"));
01389 return nt_status;
01390 }
01391
01392
01393 if (!build_sam_account(smbpasswd_state, sam_acct, smb_pw))
01394 return nt_status;
01395
01396
01397 return NT_STATUS_OK;
01398 }
01399
01400 static NTSTATUS smbpasswd_getsampwsid(struct pdb_methods *my_methods, struct samu *sam_acct, const DOM_SID *sid)
01401 {
01402 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
01403 struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
01404 struct smb_passwd *smb_pw;
01405 FILE *fp = NULL;
01406 fstring sid_str;
01407 uint32 rid;
01408
01409 DEBUG(10, ("smbpasswd_getsampwrid: search by sid: %s\n", sid_to_string(sid_str, sid)));
01410
01411 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
01412 return NT_STATUS_UNSUCCESSFUL;
01413
01414
01415 if (rid == DOMAIN_USER_RID_GUEST) {
01416 const char *guest_account = lp_guestaccount();
01417 if (!(guest_account && *guest_account)) {
01418 DEBUG(1, ("Guest account not specfied!\n"));
01419 return nt_status;
01420 }
01421 return smbpasswd_getsampwnam(my_methods, sam_acct, guest_account);
01422 }
01423
01424
01425 fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ, &(smbpasswd_state->pw_file_lock_depth));
01426
01427 if (fp == NULL) {
01428 DEBUG(0, ("Unable to open passdb database.\n"));
01429 return nt_status;
01430 }
01431
01432 while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL) && (algorithmic_pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) )
01433 ;
01434
01435 endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
01436
01437
01438
01439 if (smb_pw == NULL)
01440 return nt_status;
01441
01442 DEBUG(10, ("getsampwrid (smbpasswd): found by name: %s\n", smb_pw->smb_name));
01443
01444 if (!sam_acct) {
01445 DEBUG(10,("getsampwrid: (smbpasswd) struct samu is NULL\n"));
01446 return nt_status;
01447 }
01448
01449
01450 if (!build_sam_account (smbpasswd_state, sam_acct, smb_pw))
01451 return nt_status;
01452
01453
01454 if (NT_STATUS_IS_OK(nt_status) && !sid_equal(pdb_get_user_sid(sam_acct), sid)) {
01455 fstring sid_string1, sid_string2;
01456 DEBUG(1, ("looking for user with sid %s instead returned %s for account %s!?!\n",
01457 sid_to_string(sid_string1, sid), sid_to_string(sid_string2, pdb_get_user_sid(sam_acct)), pdb_get_username(sam_acct)));
01458 return NT_STATUS_NO_SUCH_USER;
01459 }
01460
01461
01462 return NT_STATUS_OK;
01463 }
01464
01465 static NTSTATUS smbpasswd_add_sam_account(struct pdb_methods *my_methods, struct samu *sampass)
01466 {
01467 struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
01468 struct smb_passwd smb_pw;
01469
01470
01471 if (!build_smb_pass(&smb_pw, sampass)) {
01472 return NT_STATUS_UNSUCCESSFUL;
01473 }
01474
01475
01476 return add_smbfilepwd_entry(smbpasswd_state, &smb_pw);
01477 }
01478
01479 static NTSTATUS smbpasswd_update_sam_account(struct pdb_methods *my_methods, struct samu *sampass)
01480 {
01481 struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
01482 struct smb_passwd smb_pw;
01483
01484
01485 if (!build_smb_pass(&smb_pw, sampass)) {
01486 DEBUG(0, ("smbpasswd_update_sam_account: build_smb_pass failed!\n"));
01487 return NT_STATUS_UNSUCCESSFUL;
01488 }
01489
01490
01491 if(!mod_smbfilepwd_entry(smbpasswd_state, &smb_pw)) {
01492 DEBUG(0, ("smbpasswd_update_sam_account: mod_smbfilepwd_entry failed!\n"));
01493 return NT_STATUS_UNSUCCESSFUL;
01494 }
01495
01496 return NT_STATUS_OK;
01497 }
01498
01499 static NTSTATUS smbpasswd_delete_sam_account (struct pdb_methods *my_methods, struct samu *sampass)
01500 {
01501 struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
01502
01503 const char *username = pdb_get_username(sampass);
01504
01505 if (del_smbfilepwd_entry(smbpasswd_state, username))
01506 return NT_STATUS_OK;
01507
01508 return NT_STATUS_UNSUCCESSFUL;
01509 }
01510
01511 static NTSTATUS smbpasswd_rename_sam_account (struct pdb_methods *my_methods,
01512 struct samu *old_acct,
01513 const char *newname)
01514 {
01515 pstring rename_script;
01516 struct samu *new_acct = NULL;
01517 BOOL interim_account = False;
01518 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
01519
01520 if (!*(lp_renameuser_script()))
01521 goto done;
01522
01523 if ( !(new_acct = samu_new( NULL )) ) {
01524 return NT_STATUS_NO_MEMORY;
01525 }
01526
01527 if ( !pdb_copy_sam_account( new_acct, old_acct )
01528 || !pdb_set_username(new_acct, newname, PDB_CHANGED))
01529 {
01530 goto done;
01531 }
01532
01533 ret = smbpasswd_add_sam_account(my_methods, new_acct);
01534 if (!NT_STATUS_IS_OK(ret))
01535 goto done;
01536
01537 interim_account = True;
01538
01539
01540 pstrcpy(rename_script, lp_renameuser_script());
01541
01542 if (*rename_script) {
01543 int rename_ret;
01544
01545 string_sub2(rename_script, "%unew", newname, sizeof(pstring),
01546 True, False, True);
01547 string_sub2(rename_script, "%uold", pdb_get_username(old_acct),
01548 sizeof(pstring), True, False, True);
01549
01550 rename_ret = smbrun(rename_script, NULL);
01551
01552 DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
01553
01554 if (rename_ret == 0) {
01555 smb_nscd_flush_user_cache();
01556 }
01557
01558 if (rename_ret)
01559 goto done;
01560 } else {
01561 goto done;
01562 }
01563
01564 smbpasswd_delete_sam_account(my_methods, old_acct);
01565 interim_account = False;
01566
01567 done:
01568
01569 if (interim_account)
01570 smbpasswd_delete_sam_account(my_methods, new_acct);
01571
01572 if (new_acct)
01573 TALLOC_FREE(new_acct);
01574
01575 return (ret);
01576 }
01577
01578 static BOOL smbpasswd_rid_algorithm(struct pdb_methods *methods)
01579 {
01580 return True;
01581 }
01582
01583 static void free_private_data(void **vp)
01584 {
01585 struct smbpasswd_privates **privates = (struct smbpasswd_privates**)vp;
01586
01587 endsmbfilepwent((*privates)->pw_file, &((*privates)->pw_file_lock_depth));
01588
01589 *privates = NULL;
01590
01591 }
01592
01593 static NTSTATUS pdb_init_smbpasswd( struct pdb_methods **pdb_method, const char *location )
01594 {
01595 NTSTATUS nt_status;
01596 struct smbpasswd_privates *privates;
01597
01598 if ( !NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method )) ) {
01599 return nt_status;
01600 }
01601
01602 (*pdb_method)->name = "smbpasswd";
01603
01604 (*pdb_method)->setsampwent = smbpasswd_setsampwent;
01605 (*pdb_method)->endsampwent = smbpasswd_endsampwent;
01606 (*pdb_method)->getsampwent = smbpasswd_getsampwent;
01607 (*pdb_method)->getsampwnam = smbpasswd_getsampwnam;
01608 (*pdb_method)->getsampwsid = smbpasswd_getsampwsid;
01609 (*pdb_method)->add_sam_account = smbpasswd_add_sam_account;
01610 (*pdb_method)->update_sam_account = smbpasswd_update_sam_account;
01611 (*pdb_method)->delete_sam_account = smbpasswd_delete_sam_account;
01612 (*pdb_method)->rename_sam_account = smbpasswd_rename_sam_account;
01613
01614 (*pdb_method)->rid_algorithm = smbpasswd_rid_algorithm;
01615
01616
01617
01618 if ( !(privates = TALLOC_ZERO_P( *pdb_method, struct smbpasswd_privates )) ) {
01619 DEBUG(0, ("talloc() failed for smbpasswd private_data!\n"));
01620 return NT_STATUS_NO_MEMORY;
01621 }
01622
01623
01624
01625 if (location) {
01626 privates->smbpasswd_file = talloc_strdup(*pdb_method, location);
01627 } else {
01628 privates->smbpasswd_file = talloc_strdup(*pdb_method, lp_smb_passwd_file());
01629 }
01630
01631 if (!privates->smbpasswd_file) {
01632 DEBUG(0, ("talloc_strdp() failed for storing smbpasswd location!\n"));
01633 return NT_STATUS_NO_MEMORY;
01634 }
01635
01636 (*pdb_method)->private_data = privates;
01637
01638 (*pdb_method)->free_private_data = free_private_data;
01639
01640 return NT_STATUS_OK;
01641 }
01642
01643 NTSTATUS pdb_smbpasswd_init(void)
01644 {
01645 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "smbpasswd", pdb_init_smbpasswd);
01646 }