From ec934124db8a5234d8c83799a23c7bdced5dd95a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 29 Aug 2005 22:01:18 +0000 Subject: r9762: Add support for reading good old smbpasswd files Fix password support Make base64 decode/encode functions available to EJS (This used to be commit 1376a1fe44cd6b01709819095a711c14626b1d3e) --- source4/lib/samba3/samba3.h | 4 +- source4/lib/samba3/smbpasswd.c | 132 +++++++++++++++++++++++++++++++++++++++++ source4/lib/samba3/tdbsam.c | 32 +++++----- 3 files changed, 151 insertions(+), 17 deletions(-) (limited to 'source4/lib/samba3') diff --git a/source4/lib/samba3/samba3.h b/source4/lib/samba3/samba3.h index 5aba790c4e..a41109a145 100644 --- a/source4/lib/samba3/samba3.h +++ b/source4/lib/samba3/samba3.h @@ -22,6 +22,7 @@ #define _SAMBA3_H #include "librpc/gen_ndr/security.h" +#include "librpc/gen_ndr/samr.h" struct samba3_samaccount { uint32_t logon_time, @@ -43,10 +44,11 @@ struct samba3_samaccount { char *profile_path; char *acct_desc; char *workstations; + uid_t uid; uint32_t user_rid, group_rid, hours_len, unknown_6; uint16_t acct_ctrl, logon_divs; uint16_t bad_password_count, logon_count; - uint8_t *lm_pw_ptr, *nt_pw_ptr; + struct samr_Password lm_pw, nt_pw; uint8_t *nt_pw_hist_ptr; uint8_t *hours; }; diff --git a/source4/lib/samba3/smbpasswd.c b/source4/lib/samba3/smbpasswd.c index bcbb5e56d8..5976d2db57 100644 --- a/source4/lib/samba3/smbpasswd.c +++ b/source4/lib/samba3/smbpasswd.c @@ -7,6 +7,7 @@ Modified by Gerald (Jerry) Carter 2000-2001 Copyright (C) Tim Potter 2001 Copyright (C) Andrew Bartlett 2005 + Copyright (C) Jelmer Vernooij 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -54,6 +55,7 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_samr.h" +#include "lib/samba3/samba3.h" #include "system/iconv.h" /*! Convert 32 hex characters into a 16 byte array. */ @@ -206,3 +208,133 @@ char *smbpasswd_encode_acb_info(TALLOC_CTX *mem_ctx, uint16_t acb_info) return acct_str; } + +NTSTATUS samba3_read_smbpasswd(const char *filename, TALLOC_CTX *ctx, struct samba3_samaccount **accounts, uint32_t *count) +{ + int numlines; + char **lines; + *count = 0; + *accounts = NULL; + int i; + + lines = file_lines_load(filename, &numlines, ctx); + + *accounts = talloc_array(ctx, struct samba3_samaccount, numlines); + + for (i = 0; i < numlines; i++) { + char *p = lines[i], *q; + struct samba3_samaccount *acc = &((*accounts)[*count]); + + if (p[0] == '\0' || p[0] == '#') + continue; + + ZERO_STRUCTP(acc); + + q = strchr(p, ':'); + if (!q) { + DEBUG(0, ("%s:%d: expected ':'\n", filename, i)); + continue; + } + + acc->username = talloc_strndup(ctx, p, PTR_DIFF(q, p)); + p = q+1; + + acc->uid = atoi(p); + + q = strchr(p, ':'); + if (!q) { + DEBUG(0, ("%s:%d: expected ':'\n", filename, i)); + continue; + } + p = q+1; + + if (strlen(p) < 33) { + DEBUG(0, ("%s:%d: expected 32 byte password blob\n", filename, i)); + continue; + } + + if (!strncmp(p, "NO PASSWORD", strlen("NO PASSWORD"))) { + acc->acct_ctrl |= ACB_PWNOTREQ; + } else if (p[0] == '*' || p[0] == 'X') { + /* No password set */ + } else { + struct samr_Password *pw = smbpasswd_gethexpwd(*accounts, p); + + if (!pw) { + DEBUG(0, ("%s:%d: Malformed LM pw entry\n", filename, i)); + continue; + } + + memcpy(acc->lm_pw.hash, pw, sizeof(*pw)); + } + + if (p[32] != ':') { + DEBUG(0, ("%s:%d: expected ':' after 32 byte password blob\n", filename, i)); + continue; + } + + p += 33; + + if (p[0] == '*' || p[0] == 'X') { + /* No password set */ + } else { + struct samr_Password *pw = smbpasswd_gethexpwd(*accounts, p); + + if (!pw) { + DEBUG(0, ("%s:%d: Malformed LM pw entry\n", filename, i)); + continue; + } + + memcpy(acc->nt_pw.hash, pw, sizeof(*pw)); + } + + if (p[32] != ':') { + DEBUG(0, ("%s:%d: expected ':' after 32 byte password blob\n", filename, i)); + continue; + } + + p += 33; + + if (p[0] == '[') { + q = strchr(p, ']'); + if (!q) { + DEBUG(0, ("%s:%d: expected ']'\n", filename, i)); + continue; + } + + acc->acct_ctrl |= smbpasswd_decode_acb_info(p); + + p = q+1; + if (p[0] == ':' && strncmp(p, "LCT-", 4) == 0) { + int j; + p += 4; + + for(j = 0; j < 8; j++) { + if(p[j] == '\0' || !isxdigit(p[j])) { + break; + } + } + if(i == 8) { + acc->pass_last_set_time = (time_t)strtol((char *)p, NULL, 16); + } + } + } else { + /* 'Old' style file. Fake up based on user name. */ + /* + * Currently trust accounts are kept in the same + * password file as 'normal accounts'. If this changes + * we will have to fix this code. JRA. + */ + if(acc->username[strlen(acc->username) - 1] == '$') { + acc->acct_ctrl &= ~ACB_NORMAL; + acc->acct_ctrl |= ACB_WSTRUST; + } + } + + (*count)++; + } + + talloc_free(lines); + + return NT_STATUS_OK; +} diff --git a/source4/lib/samba3/tdbsam.c b/source4/lib/samba3/tdbsam.c index c9b121ca77..fc293d5df9 100644 --- a/source4/lib/samba3/tdbsam.c +++ b/source4/lib/samba3/tdbsam.c @@ -69,8 +69,8 @@ static BOOL init_sam_from_buffer_v0(TDB_CONTEXT *tdb, struct samba3_samaccount * &munged_dial_len, &sampass->munged_dial, /* B */ &sampass->user_rid, /* d */ &sampass->group_rid, /* d */ - &lm_pw_len, &sampass->lm_pw_ptr, /* B */ - &nt_pw_len, &sampass->nt_pw_ptr, /* B */ + &lm_pw_len, sampass->lm_pw.hash, /* B */ + &nt_pw_len, sampass->nt_pw.hash, /* B */ &sampass->acct_ctrl, /* w */ &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */ &sampass->logon_divs, /* w */ @@ -85,11 +85,11 @@ static BOOL init_sam_from_buffer_v0(TDB_CONTEXT *tdb, struct samba3_samaccount * } if (lm_pw_len != 16) { - sampass->lm_pw_ptr = NULL; + return False; } if (nt_pw_len != 16) { - sampass->nt_pw_ptr = NULL; + return False; } return True; @@ -135,8 +135,8 @@ static BOOL init_sam_from_buffer_v1(TDB_CONTEXT *tdb, struct samba3_samaccount * &munged_dial_len, &sampass->munged_dial, /* B */ &sampass->user_rid, /* d */ &sampass->group_rid, /* d */ - &lm_pw_len, &sampass->lm_pw_ptr, /* B */ - &nt_pw_len, &sampass->nt_pw_ptr, /* B */ + &lm_pw_len, sampass->lm_pw.hash, /* B */ + &nt_pw_len, sampass->nt_pw.hash, /* B */ &sampass->acct_ctrl, /* w */ &remove_me, /* d */ &sampass->logon_divs, /* w */ @@ -150,12 +150,12 @@ static BOOL init_sam_from_buffer_v1(TDB_CONTEXT *tdb, struct samba3_samaccount * return False; } - if (sampass->lm_pw_ptr && lm_pw_len != 16) { - sampass->lm_pw_ptr = NULL; + if (lm_pw_len != 16) { + return False; } - if (sampass->nt_pw_ptr && nt_pw_len != 16) { - sampass->nt_pw_ptr = NULL; + if (nt_pw_len != 16) { + return False; } return True; @@ -199,8 +199,8 @@ static BOOL init_sam_from_buffer_v2(TDB_CONTEXT *tdb, struct samba3_samaccount * &munged_dial_len, &sampass->munged_dial, /* B */ &sampass->user_rid, /* d */ &sampass->group_rid, /* d */ - &lm_pw_len, &sampass->lm_pw_ptr, /* B */ - &nt_pw_len, &sampass->nt_pw_ptr, /* B */ + &lm_pw_len, sampass->lm_pw.hash, /* B */ + &nt_pw_len, sampass->nt_pw.hash, /* B */ /* Change from V1 is addition of password history field. */ &nt_pw_hist_len, &sampass->nt_pw_hist_ptr, /* B */ &sampass->acct_ctrl, /* w */ @@ -216,12 +216,12 @@ static BOOL init_sam_from_buffer_v2(TDB_CONTEXT *tdb, struct samba3_samaccount * return False; } - if (sampass->lm_pw_ptr && lm_pw_len != 16) { - sampass->lm_pw_ptr = NULL; + if (lm_pw_len != 16) { + return False; } - if (sampass->nt_pw_ptr && nt_pw_len != 16) { - sampass->nt_pw_ptr = NULL; + if (nt_pw_len != 16) { + return False; } return True; -- cgit