diff options
author | Gerald Carter <jerry@samba.org> | 2005-03-17 22:13:36 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2005-03-17 22:13:36 +0000 |
commit | 7b804bdf24e71c91c594a4be47e64d569fddc4eb (patch) | |
tree | 012b5ae598cc1a787971d840f550a7ba4df1b049 | |
parent | df807d2059a3712571a19442543a63880d3d6c3f (diff) | |
download | samba-7b804bdf24e71c91c594a4be47e64d569fddc4eb.tar.gz |
r5870: syncing up for 3.0.12
svn merge -r5740:5743 $SVNURL/branches/SAMBA_3_0
svn merge -r5743:5746 $SVNURL/branches/SAMBA_3_0
svn merge -r5746:5749 $SVNURL/branches/SAMBA_3_0
svn merge -r5749:5751 $SVNURL/branches/SAMBA_3_0
svn merge -r5751:5752 $SVNURL/branches/SAMBA_3_0
svn merge -r5752:5757 $SVNURL/branches/SAMBA_3_0
svn merge -r5757:5759 $SVNURL/branches/SAMBA_3_0
svn merge -r5759:5760 $SVNURL/branches/SAMBA_3_0
svn merge -r5760:5762 $SVNURL/branches/SAMBA_3_0
svn merge -r5770:5776 $SVNURL/branches/SAMBA_3_0
svn merge -r5776:5786 $SVNURL/branches/SAMBA_3_0
svn merge -r5786:5789 $SVNURL/branches/SAMBA_3_0
svn merge -r5789:5790 $SVNURL/branches/SAMBA_3_0
svn merge -r5792:5804 $SVNURL/branches/SAMBA_3_0
svn merge -r5809:5812 $SVNURL/branches/SAMBA_3_0
svn merge -r5812:5813 $SVNURL/branches/SAMBA_3_0
svn merge -r5813:5816 $SVNURL/branches/SAMBA_3_0
svn merge -r5816:5817 $SVNURL/branches/SAMBA_3_0
svn merge -r5817:5820 $SVNURL/branches/SAMBA_3_0
svn merge -r5820:5825 $SVNURL/branches/SAMBA_3_0
svn merge -r5833:5835 $SVNURL/branches/SAMBA_3_0
svn merge -r5835:5836 $SVNURL/branches/SAMBA_3_0
svn merge -r5836:5840 $SVNURL/branches/SAMBA_3_0
svn merge -r5840:5843 $SVNURL/branches/SAMBA_3_0
svn merge -r5843:5844 $SVNURL/branches/SAMBA_3_0
svn merge -r5844:5847 $SVNURL/branches/SAMBA_3_0
svn merge -r5848:5851 $SVNURL/branches/SAMBA_3_0
svn merge -r5851:5854 $SVNURL/branches/SAMBA_3_0
-rw-r--r-- | examples/LDAP/samba-nds.schema | 2 | ||||
-rwxr-xr-x | examples/misc/check_multiple_LDAP_entries.pl | 201 | ||||
-rw-r--r-- | source/VERSION | 2 | ||||
-rw-r--r-- | source/client/client.c | 2 | ||||
-rw-r--r-- | source/include/popt_common.h | 2 | ||||
-rw-r--r-- | source/lib/sysacls.c | 7 | ||||
-rw-r--r-- | source/libads/kerberos_keytab.c | 23 | ||||
-rw-r--r-- | source/libads/kerberos_verify.c | 164 | ||||
-rw-r--r-- | source/libsmb/clidfs.c | 2 | ||||
-rw-r--r-- | source/libsmb/clitrans.c | 5 | ||||
-rw-r--r-- | source/libsmb/libsmbclient.c | 2 | ||||
-rw-r--r-- | source/libsmb/smb_signing.c | 5 | ||||
-rw-r--r-- | source/modules/vfs_full_audit.c | 23 | ||||
-rw-r--r-- | source/nsswitch/winbindd_passdb.c | 2 | ||||
-rw-r--r-- | source/passdb/pdb_nds.c | 36 | ||||
-rw-r--r-- | source/rpcclient/cmd_spoolss.c | 23 | ||||
-rw-r--r-- | source/smbd/dfree.c | 15 | ||||
-rw-r--r-- | source/smbd/dir.c | 4 | ||||
-rw-r--r-- | source/smbd/open.c | 12 | ||||
-rw-r--r-- | source/smbd/reply.c | 12 | ||||
-rw-r--r-- | source/smbd/trans2.c | 37 | ||||
-rw-r--r-- | source/smbd/vfs.c | 5 | ||||
-rw-r--r-- | source/torture/masktest.c | 2 | ||||
-rw-r--r-- | source/torture/nbio.c | 4 | ||||
-rw-r--r-- | source/utils/net_help.c | 2 | ||||
-rw-r--r-- | source/utils/pdbedit.c | 10 |
26 files changed, 480 insertions, 124 deletions
diff --git a/examples/LDAP/samba-nds.schema b/examples/LDAP/samba-nds.schema index c623b4da675..de01f5115a5 100644 --- a/examples/LDAP/samba-nds.schema +++ b/examples/LDAP/samba-nds.schema @@ -128,7 +128,7 @@ attributeTypes: ( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial' DESC '' EQUALIT dn: cn=schema changetype: modify add: attributetypes -attributeTypes: ( 1.3.6.1.4.1.7165.2.1.54 NAME 'sambaPasswordHistory' DESC 'Concatenated MD4 hashes of the unicode passwords used on this account' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} ) +attributeTypes: ( 1.3.6.1.4.1.7165.2.1.54 NAME 'sambaPasswordHistory' DESC 'Concatenated MD4 hashes of the unicode passwords used on this account' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} ) ## ## SID, of any type diff --git a/examples/misc/check_multiple_LDAP_entries.pl b/examples/misc/check_multiple_LDAP_entries.pl new file mode 100755 index 00000000000..00c197ace4f --- /dev/null +++ b/examples/misc/check_multiple_LDAP_entries.pl @@ -0,0 +1,201 @@ +#!/usr/bin/perl -w +# Guenther Deschner <gd@samba.org> +# +# check for multiple LDAP entries + +use strict; + +use Net::LDAP; +use Getopt::Std; + +my %opts; + +if (!@ARGV) { + print "usage: $0 -h host -b base -D admindn -w password [-l]\n"; + print "\tperforms checks for multiple sid, uid and gid-entries on your LDAP server\n"; + print "\t-l adds additional checks against the local /etc/passwd and /etc/group file\n"; + exit 1; +} + +getopts('b:h:D:w:l', \%opts); + +my $host = $opts{h} || "localhost"; +my $suffix = $opts{b} || die "please set base with -b"; +my $binddn = $opts{D} || die "please set basedn with -D"; +my $bindpw = $opts{w} || die "please set password with -w"; +my $check_local_files = $opts{l} || 0; + +######################## + + +my ($ldap, $res); +my (%passwd_h, %group_h); +my $bad_uids = 0; +my $bad_gids = 0; +my $bad_sids = 0; +my $ret = 0; + +if ($check_local_files) { + my @uids = `cut -d ':' -f 3 /etc/passwd`; + my @gids = `cut -d ':' -f 3 /etc/group`; + + foreach my $uid (@uids) { + chomp($uid); + $passwd_h{$uid} = $uid; + } + + foreach my $gid (@gids) { + chomp($gid); + $group_h{$gid} = $gid; + } +} + +######## +# bind # +######## + +$ldap = Net::LDAP->new($host, version => '3'); + +$res = $ldap->bind( $binddn, password => $bindpw); +$res->code && die "failed to bind: ", $res->error; + + + +########################### +# check for double sids # +########################### + +print "\ntesting for multiple sambaSids\n"; + +$res = $ldap->search( + base => $suffix, + filter => "(objectclass=sambaSamAccount)"); + +$res->code && die "failed to search: ", $res->error; + +foreach my $entry ($res->all_entries) { + + my $sid = $entry->get_value('sambaSid'); + + my $local_res = $ldap->search( + base => $suffix, + filter => "(&(objectclass=sambaSamAccount)(sambaSid=$sid))"); + + $local_res->code && die "failed to search: ", $local_res->error; + if ($local_res->count > 1) { + print "A SambaSamAccount with sambaSid [$sid] must exactly exist once\n"; + print "You have ", $local_res->count, " entries:\n"; + foreach my $loc_entry ($local_res->all_entries) { + printf "\t%s\n", $loc_entry->dn; + } + ++$bad_sids; + } +} + +if ($bad_sids) { + $ret = -1; + print "You have $bad_sids bad sambaSids in your system. You might need to repair them\n"; +} else { + print "No multiple sambaSids found in your system\n"; +} + +print "-" x 80, "\n"; + +########################### +# check for double groups # +########################### + +print "\ntesting for multiple gidNumbers\n"; + +$res = $ldap->search( + base => $suffix, + filter => "(objectclass=posixGroup)"); + +$res->code && die "failed to search: ", $res->error; + +foreach my $entry ($res->all_entries) { + + my $gid = $entry->get_value('gidNumber'); + my $dn = $entry->dn; + + my $local_res = $ldap->search( + base => $suffix, + filter => "(&(objectclass=posixGroup)(gidNumber=$gid))"); + + $local_res->code && die "failed to search: ", $local_res->error; + if ($local_res->count > 1) { + print "A PosixGroup with gidNumber [$gid] must exactly exist once\n"; + print "You have ", $local_res->count, " entries:\n"; + foreach my $loc_entry ($local_res->all_entries) { + printf "\t%s\n", $loc_entry->dn; + } + ++$bad_gids; + next; + } + + if ($check_local_files && exists $group_h{$gid}) { + print "Warning: There is a group in /etc/group that has gidNumber [$gid] as well\n"; + print "This entry may conflict with $dn\n"; + ++$bad_gids; + } +} + +if ($bad_gids) { + $ret = -1; + print "You have $bad_gids bad gidNumbers in your system. You might need to repair them\n"; +} else { + print "No multiple gidNumbers found in your system\n"; +} + +print "-" x 80, "\n"; + + +########################### +# check for double users # +########################### + +print "\ntesting for multiple uidNumbers\n"; + +$res = $ldap->search( + base => $suffix, + filter => "(objectclass=posixAccount)"); + +$res->code && die "failed to search: ", $res->error; + + +foreach my $entry ($res->all_entries) { + + my $uid = $entry->get_value('uidNumber'); + my $dn = $entry->dn; + + my $local_res = $ldap->search( + base => $suffix, + filter => "(&(objectclass=posixAccount)(uidNumber=$uid))"); + + $local_res->code && die "failed to search: ", $local_res->error; + if ($local_res->count > 1) { + print "A PosixAccount with uidNumber [$uid] must exactly exist once\n"; + print "You have ", $local_res->count, " entries:\n"; + foreach my $loc_entry ($local_res->all_entries) { + printf "\t%s\n", $loc_entry->dn; + } + ++$bad_uids; + next; + } + if ($check_local_files && exists $passwd_h{$uid}) { + print "Warning: There is a user in /etc/passwd that has uidNumber [$uid] as well\n"; + print "This entry may conflict with $dn\n"; + ++$bad_uids; + } +} + +if ($bad_uids) { + $ret = -1; + print "You have $bad_uids bad uidNumbers in your system. You might need to repair them\n"; +} else { + print "No multiple uidNumbers found in your system\n"; +} + +$ldap->unbind; + +exit $ret; diff --git a/source/VERSION b/source/VERSION index 99d75e80bdd..13c216d5554 100644 --- a/source/VERSION +++ b/source/VERSION @@ -39,7 +39,7 @@ SAMBA_VERSION_PRE_RELEASE= # e.g. SAMBA_VERSION_RC_RELEASE=1 # # -> "3.0.0rc1" # ######################################################## -SAMBA_VERSION_RC_RELEASE=1 +SAMBA_VERSION_RC_RELEASE= ######################################################## # To mark SVN snapshots this should be set to 'yes' # diff --git a/source/client/client.c b/source/client/client.c index b00e7f2273f..9a09d50cc08 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -43,7 +43,7 @@ static char *cmdstr = NULL; static int io_bufsize = 64512; static int name_type = 0x20; -static int max_protocol = PROTOCOL_NT1; +extern int max_protocol; static int process_tok(pstring tok); static int cmd_help(void); diff --git a/source/include/popt_common.h b/source/include/popt_common.h index 6db30fbc0ac..7c0a86836dc 100644 --- a/source/include/popt_common.h +++ b/source/include/popt_common.h @@ -21,6 +21,8 @@ #ifndef _POPT_COMMON_H #define _POPT_COMMON_H +#include <popt.h> + /* Common popt structures */ extern struct poptOption popt_common_samba[]; extern struct poptOption popt_common_connection[]; diff --git a/source/lib/sysacls.c b/source/lib/sysacls.c index 4484810884d..e7bd288f6e8 100644 --- a/source/lib/sysacls.c +++ b/source/lib/sysacls.c @@ -20,6 +20,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_ACLS + /* This file wraps all differing system ACL interfaces into a consistent one based on the POSIX interface. It also returns the correct errors @@ -2277,6 +2280,10 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type) int rc = 0; uid_t user_id; + /* AIX has no DEFAULT */ + if ( type == SMB_ACL_TYPE_DEFAULT ) + return NULL; + /* Get the acl using statacl */ DEBUG(10,("Entering sys_acl_get_file\n")); diff --git a/source/libads/kerberos_keytab.c b/source/libads/kerberos_keytab.c index 8475f70ec47..f6ed107ee00 100644 --- a/source/libads/kerberos_keytab.c +++ b/source/libads/kerberos_keytab.c @@ -440,10 +440,12 @@ int ads_keytab_create_default(ADS_STRUCT *ads) krb5_kt_cursor cursor; krb5_keytab_entry kt_entry; krb5_kvno kvno; - fstring my_fqdn, my_Fqdn, my_name, my_NAME; + fstring my_fqdn, my_Fqdn, my_name, my_NAME, my_host_realm; char *p_fqdn; int i, found = 0; - char **oldEntries = NULL, *princ_s[18];; + char **oldEntries = NULL, *princ_s[26]; + + memset(princ_s, '\0', sizeof(princ_s)); ret = ads_keytab_add_entry(ads, "host"); if (ret) { @@ -472,6 +474,11 @@ int ads_keytab_create_default(ADS_STRUCT *ads) fstrcat(my_Fqdn, p_fqdn); } + fstrcpy(my_host_realm, my_name); + fstrcat(my_host_realm, "."); + fstrcat(my_host_realm, lp_realm()); + strlower_m(my_host_realm); + asprintf(&princ_s[0], "%s$@%s", my_name, lp_realm()); asprintf(&princ_s[1], "%s$@%s", my_NAME, lp_realm()); asprintf(&princ_s[2], "host/%s@%s", my_name, lp_realm()); @@ -490,6 +497,18 @@ int ads_keytab_create_default(ADS_STRUCT *ads) asprintf(&princ_s[15], "CIFS/%s@%s", my_NAME, lp_realm()); asprintf(&princ_s[16], "CIFS/%s@%s", my_fqdn, lp_realm()); asprintf(&princ_s[17], "CIFS/%s@%s", my_Fqdn, lp_realm()); + asprintf(&princ_s[18], "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm()); + asprintf(&princ_s[19], "CIFS/%s.%s@%s", my_name, lp_realm(), lp_realm()); + asprintf(&princ_s[20], "host/%s.%s@%s", my_name, lp_realm(), lp_realm()); + asprintf(&princ_s[21], "HOST/%s.%s@%s", my_name, lp_realm(), lp_realm()); + + /* when dnsdomain == realm, don't add duplicate principal */ + if (!strequal(my_host_realm, my_fqdn)) { + asprintf(&princ_s[22], "cifs/%s@%s", my_host_realm, lp_realm()); + asprintf(&princ_s[23], "CIFS/%s@%s", my_host_realm, lp_realm()); + asprintf(&princ_s[24], "host/%s@%s", my_host_realm, lp_realm()); + asprintf(&princ_s[25], "HOST/%s@%s", my_host_realm, lp_realm()); + } for (i = 0; i < sizeof(princ_s) / sizeof(princ_s[0]); i++) { if (princ_s[i] != NULL) { diff --git a/source/libads/kerberos_verify.c b/source/libads/kerberos_verify.c index d73fc28a296..d6cca793187 100644 --- a/source/libads/kerberos_verify.c +++ b/source/libads/kerberos_verify.c @@ -42,12 +42,33 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut krb5_error_code ret = 0; BOOL auth_ok = False; krb5_keytab keytab = NULL; - fstring my_fqdn, my_name; - fstring my_Fqdn, my_NAME; - char *p_fqdn; - char *host_princ_s[18]; - krb5_principal host_princ; + krb5_kt_cursor kt_cursor; + krb5_keytab_entry kt_entry; + char *valid_princ_formats[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + char *entry_princ_s = NULL; + fstring my_name, my_fqdn; int i; + int number_matched_principals = 0; + + /* Generate the list of principal names which we expect + * clients might want to use for authenticating to the file + * service. We allow name$,{host,cifs}/{name,fqdn,name.REALM}. */ + + fstrcpy(my_name, global_myname()); + + my_fqdn[0] = '\0'; + name_to_fqdn(my_fqdn, global_myname()); + + asprintf(&valid_princ_formats[0], "%s$@%s", my_name, lp_realm()); + asprintf(&valid_princ_formats[1], "host/%s@%s", my_name, lp_realm()); + asprintf(&valid_princ_formats[2], "host/%s@%s", my_fqdn, lp_realm()); + asprintf(&valid_princ_formats[3], "host/%s.%s@%s", my_name, lp_realm(), lp_realm()); + asprintf(&valid_princ_formats[4], "cifs/%s@%s", my_name, lp_realm()); + asprintf(&valid_princ_formats[5], "cifs/%s@%s", my_fqdn, lp_realm()); + asprintf(&valid_princ_formats[6], "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm()); + + ZERO_STRUCT(kt_entry); + ZERO_STRUCT(kt_cursor); ret = krb5_kt_default(context, &keytab); if (ret) { @@ -55,74 +76,87 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut goto out; } - /* Generate the list of principal names which we expect clients might - * want to use for authenticating to the file service. */ + /* Iterate through the keytab. For each key, if the principal + * name case-insensitively matches one of the allowed formats, + * try verifying the ticket using that principal. */ - fstrcpy(my_name, global_myname()); - strlower_m(my_name); + ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor); + if (ret) { + DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret))); + goto out; + } + + ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor); + if (ret != KRB5_KT_END && ret != ENOENT ) { + while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) { + ret = krb5_unparse_name(context, kt_entry.principal, &entry_princ_s); + if (ret) { + DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret))); + goto out; + } + + for (i = 0; i < sizeof(valid_princ_formats) / sizeof(valid_princ_formats[0]); i++) { + if (strequal(entry_princ_s, valid_princ_formats[i])) { + number_matched_principals++; + p_packet->length = ticket->length; + p_packet->data = (krb5_pointer)ticket->data; + *pp_tkt = NULL; + ret = krb5_rd_req(context, &auth_context, p_packet, kt_entry.principal, keytab, NULL, pp_tkt); + if (ret) { + DEBUG(10, ("ads_keytab_verify_ticket: krb5_rd_req(%s) failed: %s\n", + entry_princ_s, error_message(ret))); + } else { + DEBUG(3,("ads_keytab_verify_ticket: krb5_rd_req succeeded for principal %s\n", + entry_princ_s)); + auth_ok = True; + break; + } + } + } + + /* Free the name we parsed. */ + krb5_free_unparsed_name(context, entry_princ_s); + entry_princ_s = NULL; + + /* Free the entry we just read. */ + smb_krb5_kt_free_entry(context, &kt_entry); + ZERO_STRUCT(kt_entry); + } + krb5_kt_end_seq_get(context, keytab, &kt_cursor); + } - fstrcpy(my_NAME, global_myname()); - strupper_m(my_NAME); + ZERO_STRUCT(kt_cursor); - my_fqdn[0] = '\0'; - name_to_fqdn(my_fqdn, global_myname()); - strlower_m(my_fqdn); - - p_fqdn = strchr_m(my_fqdn, '.'); - fstrcpy(my_Fqdn, my_NAME); - if (p_fqdn) { - fstrcat(my_Fqdn, p_fqdn); - } - - asprintf(&host_princ_s[0], "%s$@%s", my_name, lp_realm()); - asprintf(&host_princ_s[1], "%s$@%s", my_NAME, lp_realm()); - asprintf(&host_princ_s[2], "host/%s@%s", my_name, lp_realm()); - asprintf(&host_princ_s[3], "host/%s@%s", my_NAME, lp_realm()); - asprintf(&host_princ_s[4], "host/%s@%s", my_fqdn, lp_realm()); - asprintf(&host_princ_s[5], "host/%s@%s", my_Fqdn, lp_realm()); - asprintf(&host_princ_s[6], "HOST/%s@%s", my_name, lp_realm()); - asprintf(&host_princ_s[7], "HOST/%s@%s", my_NAME, lp_realm()); - asprintf(&host_princ_s[8], "HOST/%s@%s", my_fqdn, lp_realm()); - asprintf(&host_princ_s[9], "HOST/%s@%s", my_Fqdn, lp_realm()); - asprintf(&host_princ_s[10], "cifs/%s@%s", my_name, lp_realm()); - asprintf(&host_princ_s[11], "cifs/%s@%s", my_NAME, lp_realm()); - asprintf(&host_princ_s[12], "cifs/%s@%s", my_fqdn, lp_realm()); - asprintf(&host_princ_s[13], "cifs/%s@%s", my_Fqdn, lp_realm()); - asprintf(&host_princ_s[14], "CIFS/%s@%s", my_name, lp_realm()); - asprintf(&host_princ_s[15], "CIFS/%s@%s", my_NAME, lp_realm()); - asprintf(&host_princ_s[16], "CIFS/%s@%s", my_fqdn, lp_realm()); - asprintf(&host_princ_s[17], "CIFS/%s@%s", my_Fqdn, lp_realm()); - - /* Now try to verify the ticket using the key associated with each of - * the principals which we think clients will expect us to be - * participating as. */ - for (i = 0; i < sizeof(host_princ_s) / sizeof(host_princ_s[0]); i++) { - host_princ = NULL; - ret = krb5_parse_name(context, host_princ_s[i], &host_princ); - if (ret) { - DEBUG(1, ("ads_keytab_verify_ticket: krb5_parse_name(%s) failed (%s)\n", - host_princ_s[i], error_message(ret))); - goto out; - } - p_packet->length = ticket->length; - p_packet->data = (krb5_pointer)ticket->data; - *pp_tkt = NULL; - ret = krb5_rd_req(context, &auth_context, p_packet, host_princ, keytab, NULL, pp_tkt); - krb5_free_principal(context, host_princ); - if (ret) { - DEBUG(10, ("krb5_rd_req(%s) failed: %s\n", host_princ_s[i], error_message(ret))); + out: + + if (!auth_ok) { + if (!number_matched_principals) { + DEBUG(3, ("ads_keytab_verify_ticket: no keytab principals matched expected file service name.\n")); } else { - DEBUG(10,("krb5_rd_req succeeded for principal %s\n", host_princ_s[i])); - auth_ok = True; - break; - } + DEBUG(3, ("ads_keytab_verify_ticket: krb5_rd_req failed for all %d matched keytab principals\n", + number_matched_principals)); + } } - for (i = 0; i < sizeof(host_princ_s) / sizeof(host_princ_s[0]); i++) { - SAFE_FREE(host_princ_s[i]); + if (entry_princ_s) { + krb5_free_unparsed_name(context, entry_princ_s); } - out: + { + krb5_keytab_entry zero_kt_entry; + ZERO_STRUCT(zero_kt_entry); + if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { + smb_krb5_kt_free_entry(context, &kt_entry); + } + } + + { + krb5_kt_cursor zero_csr; + ZERO_STRUCT(zero_csr); + if ((memcmp(&kt_cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) { + krb5_kt_end_seq_get(context, keytab, &kt_cursor); + } + } if (keytab) { krb5_kt_close(context, keytab); diff --git a/source/libsmb/clidfs.c b/source/libsmb/clidfs.c index e4308fdb5a4..dcffdf42fe4 100644 --- a/source/libsmb/clidfs.c +++ b/source/libsmb/clidfs.c @@ -37,10 +37,10 @@ static pstring password; static BOOL use_kerberos; static BOOL got_pass; static int signing_state; +int max_protocol = PROTOCOL_NT1; static int port; static int name_type = 0x20; -static int max_protocol = PROTOCOL_NT1; static BOOL have_ip; static struct in_addr dest_ip; diff --git a/source/libsmb/clitrans.c b/source/libsmb/clitrans.c index 3f1afa75d69..27da63ccdad 100644 --- a/source/libsmb/clitrans.c +++ b/source/libsmb/clitrans.c @@ -195,11 +195,12 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, /* * An NT RPC pipe call can return ERRDOS, ERRmoredata * to a trans call. This is not an error and should not - * be treated as such. + * be treated as such. Note that STATUS_NO_MORE_FILES is + * returned when a trans2 findfirst/next finishes. */ status = cli_nt_error(cli); - if (NT_STATUS_IS_ERR(status)) { + if (NT_STATUS_IS_ERR(status) || NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES)) { cli_signing_trans_stop(cli); return False; } diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c index 441ca96478b..3761074e04f 100644 --- a/source/libsmb/libsmbclient.c +++ b/source/libsmb/libsmbclient.c @@ -4094,7 +4094,6 @@ int smbc_setxattr_ctx(SMBCCTX *context, dos_attr_parse(context, dad, srv, namevalue); /* Set the new DOS attributes */ -#warning "Should try Set Path Info first, but it's not yet implemented" #if 0 /* not yet implemented */ if (! cli_setpathinfo(&srv->cli, path, dad->c_time, @@ -4233,7 +4232,6 @@ int smbc_setxattr_ctx(SMBCCTX *context, dos_attr_parse(context, dad, srv, namevalue); /* Set the new DOS attributes */ -#warning "Should try Set Path Info first, but it's not yet implemented" #if 0 /* not yet implemented */ ret2 = cli_setpathinfo(&srv->cli, path, dad->c_time, diff --git a/source/libsmb/smb_signing.c b/source/libsmb/smb_signing.c index df69ff3e41f..500ff7cc6e2 100644 --- a/source/libsmb/smb_signing.c +++ b/source/libsmb/smb_signing.c @@ -277,14 +277,17 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, MD5Init(&md5_ctx); /* intialise with the key */ + MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); +#if 0 + /* JRA - apparently this is incorrect. */ /* NB. When making and verifying SMB signatures, Windows apparently zero-pads the key to 128 bits if it isn't long enough. From Nalin Dahyabhai <nalin@redhat.com> */ - MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); if (data->mac_key.length < sizeof(key_buf)) { memset(key_buf, 0, sizeof(key_buf)); MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - data->mac_key.length); } +#endif /* copy in the first bit of the SMB header */ MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4); diff --git a/source/modules/vfs_full_audit.c b/source/modules/vfs_full_audit.c index 09215d1e8d0..430ec8278a0 100644 --- a/source/modules/vfs_full_audit.c +++ b/source/modules/vfs_full_audit.c @@ -82,6 +82,10 @@ static int smb_full_audit_set_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt); +static int smb_full_audit_get_shadow_copy_data(struct vfs_handle_struct *handle, + struct files_struct *fsp, + SHADOW_COPY_DATA *shadow_copy_data, BOOL labels); + static DIR *smb_full_audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname); static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle, @@ -303,6 +307,8 @@ static vfs_op_tuple audit_op_tuples[] = { SMB_VFS_LAYER_LOGGER}, {SMB_VFS_OP(smb_full_audit_set_quota), SMB_VFS_OP_SET_QUOTA, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA, + SMB_VFS_LAYER_LOGGER}, /* Directory operations */ @@ -395,9 +401,9 @@ static vfs_op_tuple audit_op_tuples[] = { /* POSIX ACL operations. */ - {SMB_VFS_OP(smb_full_audit_chmod_acl), SMB_VFS_OP_CHMOD, + {SMB_VFS_OP(smb_full_audit_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER}, - {SMB_VFS_OP(smb_full_audit_fchmod_acl), SMB_VFS_OP_FCHMOD, + {SMB_VFS_OP(smb_full_audit_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER}, {SMB_VFS_OP(smb_full_audit_sys_acl_get_entry), SMB_VFS_OP_SYS_ACL_GET_ENTRY, SMB_VFS_LAYER_LOGGER}, @@ -788,6 +794,19 @@ static int smb_full_audit_set_quota(struct vfs_handle_struct *handle, return result; } +static int smb_full_audit_get_shadow_copy_data(struct vfs_handle_struct *handle, + struct files_struct *fsp, + SHADOW_COPY_DATA *shadow_copy_data, BOOL labels) +{ + int result; + + result = SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp, shadow_copy_data, labels); + + do_log(SMB_VFS_OP_GET_SHADOW_COPY_DATA, (result >= 0), handle, ""); + + return result; +} + static DIR *smb_full_audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname) { diff --git a/source/nsswitch/winbindd_passdb.c b/source/nsswitch/winbindd_passdb.c index 554687d7b83..bd15777bd31 100644 --- a/source/nsswitch/winbindd_passdb.c +++ b/source/nsswitch/winbindd_passdb.c @@ -295,7 +295,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, static NTSTATUS lookup_useraliases(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, uint32 num_sids, DOM_SID **sids, - uint32 *num_aliases, DOM_SID ***aliases) + uint32 *num_aliases, uint32 **aliases) { return NT_STATUS_NO_SUCH_USER; } diff --git a/source/passdb/pdb_nds.c b/source/passdb/pdb_nds.c index 4d91b5b8672..06060d4067a 100644 --- a/source/passdb/pdb_nds.c +++ b/source/passdb/pdb_nds.c @@ -764,6 +764,7 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods, char protocol[12]; char ldap_server[256]; const char *username = pdb_get_username(sam_acct); + BOOL got_clear_text_pw = False; DEBUG(5,("pdb_nds_update_login_attempts: %s login for %s\n", success ? "Successful" : "Failed", username)); @@ -795,7 +796,8 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods, pwd_len = sizeof(clear_text_pw); if (success == True) { if (pdb_nds_get_password(ldap_state->smbldap_state, dn, &pwd_len, clear_text_pw) == LDAP_SUCCESS) { - /* */ + /* Got clear text password. Use simple ldap bind */ + got_clear_text_pw = True; } } else { generate_random_buffer(clear_text_pw, 24); @@ -849,22 +851,24 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods, } } - /* Attempt simple bind with real or bogus password */ - rc = ldap_simple_bind_s(ld, dn, clear_text_pw); - if (rc == LDAP_SUCCESS) { - DEBUG(5,("pdb_nds_update_login_attempts: ldap_simple_bind_s Successful for %s\n", username)); - ldap_unbind_ext(ld, NULL, NULL); - } else { - NTSTATUS nt_status = NT_STATUS_ACCOUNT_RESTRICTION; - DEBUG(5,("pdb_nds_update_login_attempts: ldap_simple_bind_s Failed for %s\n", username)); - switch(rc) { - case LDAP_INVALID_CREDENTIALS: - nt_status = NT_STATUS_WRONG_PASSWORD; - break; - default: - break; + if((success != True) || (got_clear_text_pw == True)) { + /* Attempt simple bind with real or bogus password */ + rc = ldap_simple_bind_s(ld, dn, clear_text_pw); + if (rc == LDAP_SUCCESS) { + DEBUG(5,("pdb_nds_update_login_attempts: ldap_simple_bind_s Successful for %s\n", username)); + ldap_unbind_ext(ld, NULL, NULL); + } else { + NTSTATUS nt_status = NT_STATUS_ACCOUNT_RESTRICTION; + DEBUG(5,("pdb_nds_update_login_attempts: ldap_simple_bind_s Failed for %s\n", username)); + switch(rc) { + case LDAP_INVALID_CREDENTIALS: + nt_status = NT_STATUS_WRONG_PASSWORD; + break; + default: + break; + } + return nt_status; } - return nt_status; } } diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c index fa77af4145d..49f22b36546 100644 --- a/source/rpcclient/cmd_spoolss.c +++ b/source/rpcclient/cmd_spoolss.c @@ -1925,6 +1925,20 @@ static WERROR cmd_spoolss_deleteform(struct cli_state *cli, /* Enumerate forms */ +static const char *get_form_flag(int form_flag) +{ + switch (form_flag) { + case FORM_USER: + return "FORM_USER"; + case FORM_BUILTIN: + return "FORM_BUILTIN"; + case FORM_PRINTER: + return "FORM_PRINTER"; + default: + return "unknown"; + } +} + static WERROR cmd_spoolss_enum_forms(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) @@ -1980,7 +1994,14 @@ static WERROR cmd_spoolss_enum_forms(struct cli_state *cli, rpcstr_pull(form_name, forms[i].name.buffer, sizeof(form_name), -1, STR_TERMINATE); - printf("%s\n", form_name); + printf("%s\n" \ + "\tflag: %s (%d)\n" \ + "\twidth: %d, length: %d\n" \ + "\tleft: %d, right: %d, top: %d, bottom: %d\n\n", + form_name, get_form_flag(forms[i].flag), forms[i].flag, + forms[i].width, forms[i].length, + forms[i].left, forms[i].right, + forms[i].top, forms[i].bottom); } done: diff --git a/source/smbd/dfree.c b/source/smbd/dfree.c index c556c8c8ab2..81a48b94fcc 100644 --- a/source/smbd/dfree.c +++ b/source/smbd/dfree.c @@ -115,10 +115,19 @@ static SMB_BIG_UINT disk_free(const char *path, BOOL small_query, } else { DEBUG (0, ("disk_free: sys_popen() failed for command %s. Error was : %s\n", syscmd, strerror(errno) )); - sys_fsusage(path, dfree, dsize); + if (sys_fsusage(path, dfree, dsize) != 0) { + DEBUG (0, ("disk_free: sys_fsusage() failed. Error was : %s\n", + strerror(errno) )); + return (SMB_BIG_UINT)-1; + } + } + } else { + if (sys_fsusage(path, dfree, dsize) != 0) { + DEBUG (0, ("disk_free: sys_fsusage() failed. Error was : %s\n", + strerror(errno) )); + return (SMB_BIG_UINT)-1; } - } else - sys_fsusage(path, dfree, dsize); + } if (disk_quotas(path, &bsize_q, &dfree_q, &dsize_q)) { (*bsize) = bsize_q; diff --git a/source/smbd/dir.c b/source/smbd/dir.c index d9fd382d520..db16b8a6e00 100644 --- a/source/smbd/dir.c +++ b/source/smbd/dir.c @@ -594,10 +594,8 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, SMB_STRUCT_STAT *pst) { - BOOL ret; - ZERO_STRUCTP(pst); - while ((ret = SearchDir(dptr->dir_hnd, name, poffset)) == True) { + while (SearchDir(dptr->dir_hnd, name, poffset) == True) { if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) { return True; } diff --git a/source/smbd/open.c b/source/smbd/open.c index a552dc5b610..0a3903234dd 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -1061,17 +1061,15 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_ oplock_request = 0; } - /* this is for OS/2 EAs - try and say we don't support them */ + /* this is for OS/2 long file names - say we don't support them */ if (strstr(fname,".+,;=[].")) { unix_ERR_class = ERRDOS; /* OS/2 Workplace shell fix may be main code stream in a later release. */ -#if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */ unix_ERR_code = ERRcannotopen; -#else /* OS2_WPS_FIX */ - unix_ERR_code = ERROR_EAS_NOT_SUPPORTED; -#endif /* OS2_WPS_FIX */ - - DEBUG(5,("open_file_shared: OS/2 EA's are not supported.\n")); + unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_NOT_FOUND; + DEBUG(5,("open_file_shared: OS/2 long filenames are not supported.\n")); + /* need to reset errno or DEVELOPER will cause us to coredump */ + errno = 0; file_free(fsp); return NULL; } diff --git a/source/smbd/reply.c b/source/smbd/reply.c index f149b79f793..d7fe5cd98f1 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -701,6 +701,8 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size return ERROR_NT(status); } + RESOLVE_DFSPATH(fname, conn, inbuf, outbuf); + unix_convert(fname,conn,0,&bad_path,&sbuf); if (bad_path) { END_PROFILE(SMBsetatr); @@ -749,7 +751,10 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz SMB_BIG_UINT dfree,dsize,bsize; START_PROFILE(SMBdskattr); - SMB_VFS_DISK_FREE(conn,".",True,&bsize,&dfree,&dsize); + if (SMB_VFS_DISK_FREE(conn,".",True,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { + END_PROFILE(SMBdskattr); + return(UNIXERROR(ERRHRD,ERRgeneral)); + } outsize = set_message(outbuf,5,0,True); @@ -833,6 +838,9 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size END_PROFILE(SMBsearch); return ERROR_NT(nt_status); } + + RESOLVE_DFSPATH(path, conn, inbuf, outbuf); + p++; status_len = SVAL(p, 0); p += 2; @@ -4449,6 +4457,8 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size return ERROR_NT(status); } + RESOLVE_DFSPATH(newdir, conn, inbuf, outbuf); + if (strlen(newdir) == 0) { ok = True; } else { diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index 3f3d9c2f461..05ff7d6785d 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -143,7 +143,7 @@ static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_str } else { pea->name = ea_name; } - pea->value.data = val; + pea->value.data = (unsigned char *)val; pea->value.length = (size_t)sizeret; return True; } @@ -1485,12 +1485,18 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", /* * If there are no matching entries we must return ERRDOS/ERRbadfile - - * from observation of NT. + * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if + * the protocol level is less than NT1. Tested with smbclient. JRA. + * This should fix the OS/2 client bug #2335. */ if(numentries == 0) { dptr_close(&dptr_num); - return ERROR_DOS(ERRDOS,ERRbadfile); + if (Protocol < PROTOCOL_NT1) { + return ERROR_DOS(ERRDOS,ERRnofiles); + } else { + return ERROR_BOTH(NT_STATUS_NO_SUCH_FILE,ERRDOS,ERRbadfile); + } } /* At this point pdata points to numentries directory entries. */ @@ -1569,7 +1575,17 @@ static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbu srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, True); if (!NT_STATUS_IS_OK(ntstatus)) { - return ERROR_NT(ntstatus); + /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to + complain (it thinks we're asking for the directory above the shared + path or an invalid name). Catch this as the resume name is only compared, never used in + a file access. JRA. */ + if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) { + pstrcpy(resume_name, ".."); + } else if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_NAME_INVALID)) { + pstrcpy(resume_name, "."); + } else { + return ERROR_NT(ntstatus); + } } DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \ @@ -1775,7 +1791,10 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf { SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 18; - SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize); + if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { + return(UNIXERROR(ERRHRD,ERRgeneral)); + } + block_size = lp_block_size(snum); if (bsize < block_size) { SMB_BIG_UINT factor = block_size/bsize; @@ -1867,7 +1886,9 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsi { SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 24; - SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize); + if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { + return(UNIXERROR(ERRHRD,ERRgeneral)); + } block_size = lp_block_size(snum); if (bsize < block_size) { SMB_BIG_UINT factor = block_size/bsize; @@ -1897,7 +1918,9 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned { SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; data_len = 32; - SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize); + if (SMB_VFS_DISK_FREE(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { + return(UNIXERROR(ERRHRD,ERRgeneral)); + } block_size = lp_block_size(snum); if (bsize < block_size) { SMB_BIG_UINT factor = block_size/bsize; diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c index 0102739fe39..34671b8efc6 100644 --- a/source/smbd/vfs.c +++ b/source/smbd/vfs.c @@ -552,6 +552,9 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len) len -= st.st_size; len /= 1024; /* Len is now number of 1k blocks needed. */ space_avail = SMB_VFS_DISK_FREE(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize); + if (space_avail == (SMB_BIG_UINT)-1) { + return -1; + } DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n", fsp->fsp_name, (double)st.st_size, (double)len, (double)space_avail )); @@ -940,7 +943,7 @@ BOOL reduce_name(connection_struct *conn, const pstring fname) } #endif - DEBUG(3,("reduce_name: %s reduced to %s\n", fname, p)); + DEBUG(3,("reduce_name: %s reduced to %s\n", fname, resolved_name)); if (free_resolved_name) SAFE_FREE(resolved_name); errno = saved_errno; diff --git a/source/torture/masktest.c b/source/torture/masktest.c index 67515463d15..f3c87e0c72c 100644 --- a/source/torture/masktest.c +++ b/source/torture/masktest.c @@ -255,7 +255,7 @@ struct cli_state *connect_one(char *share) static char *resultp; static file_info *f_info; -static void listfn(file_info *f, const char *s, void *state) +static void listfn(const char *mnt, file_info *f, const char *s, void *state) { if (strcmp(f->name,".") == 0) { resultp[0] = '+'; diff --git a/source/torture/nbio.c b/source/torture/nbio.c index 2e79584d23f..e6a87e68ad5 100644 --- a/source/torture/nbio.c +++ b/source/torture/nbio.c @@ -257,7 +257,7 @@ void nb_qfsinfo(int level) cli_dskattr(c, &bsize, &total, &avail); } -static void find_fn(file_info *finfo, const char *name, void *state) +static void find_fn(const char *mnt, file_info *finfo, const char *name, void *state) { /* noop */ } @@ -276,7 +276,7 @@ void nb_flush(int fnum) static int total_deleted; -static void delete_fn(file_info *finfo, const char *name, void *state) +static void delete_fn(const char *mnt, file_info *finfo, const char *name, void *state) { char *s, *n; if (finfo->name[0] == '.') return; diff --git a/source/utils/net_help.c b/source/utils/net_help.c index e25316818a5..b1c510d19e3 100644 --- a/source/utils/net_help.c +++ b/source/utils/net_help.c @@ -152,7 +152,7 @@ int net_help_share(int argc, const char **argv) "\t-M or --maxusers=<num>\t\tmax users allowed for share\n" "\t --acls\t\t\tcopies ACLs as well\n" "\t --attrs\t\t\tcopies DOS Attributes as well\n" - "\t --timestampes\t\tpreserve timestampes while copying files\n" + "\t --timestamps\t\tpreserve timestamps while copying files\n" "\t --destination\t\tmigration target server (default: localhost)\n" "\t-e or --exclude\t\t\tlist of shares to be excluded from mirroring\n" "\t-v or --verbose\t\t\tgive verbose output\n"); diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c index 3584ef0367a..c5ba59487cc 100644 --- a/source/utils/pdbedit.c +++ b/source/utils/pdbedit.c @@ -299,6 +299,7 @@ static int fix_users_list (struct pdb_context *in) static int set_user_info (struct pdb_context *in, const char *username, const char *fullname, const char *homedir, + const char *acct_desc, const char *drive, const char *script, const char *profile, const char *account_control, const char *user_sid, const char *group_sid, @@ -346,6 +347,8 @@ static int set_user_info (struct pdb_context *in, const char *username, if (fullname) pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED); + if (acct_desc) + pdb_set_acct_desc(sam_pwent, acct_desc, PDB_CHANGED); if (homedir) pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED); if (drive) @@ -641,6 +644,7 @@ int main (int argc, char **argv) uint32 setparms, checkparms; int opt; static char *full_name = NULL; + static char *acct_desc = NULL; static const char *user_name = NULL; static char *home_dir = NULL; static char *home_drive = NULL; @@ -673,13 +677,14 @@ int main (int argc, char **argv) {"verbose", 'v', POPT_ARG_NONE, &verbose, 0, "be verbose", NULL }, {"smbpasswd-style", 'w',POPT_ARG_NONE, &spstyle, 0, "give output in smbpasswd style", NULL}, {"user", 'u', POPT_ARG_STRING, &user_name, 0, "use username", "USER" }, + {"account-desc", 'N', POPT_ARG_STRING, &acct_desc, 0, "set account description", NULL}, {"fullname", 'f', POPT_ARG_STRING, &full_name, 0, "set full name", NULL}, {"homedir", 'h', POPT_ARG_STRING, &home_dir, 0, "set home directory", NULL}, {"drive", 'D', POPT_ARG_STRING, &home_drive, 0, "set home drive", NULL}, {"script", 'S', POPT_ARG_STRING, &logon_script, 0, "set logon script", NULL}, {"profile", 'p', POPT_ARG_STRING, &profile_path, 0, "set profile path", NULL}, - {"user SID", 'U', POPT_ARG_STRING, &user_sid, 0, "set user SID or RID", NULL}, - {"group SID", 'G', POPT_ARG_STRING, &group_sid, 0, "set group SID or RID", NULL}, + {"user-SID", 'U', POPT_ARG_STRING, &user_sid, 0, "set user SID or RID", NULL}, + {"group-SID", 'G', POPT_ARG_STRING, &group_sid, 0, "set group SID or RID", NULL}, {"create", 'a', POPT_ARG_NONE, &add_user, 0, "create user", NULL}, {"modify", 'r', POPT_ARG_NONE, &modify_user, 0, "modify user", NULL}, {"machine", 'm', POPT_ARG_NONE, &machine, 0, "account is a machine account", NULL}, @@ -960,6 +965,7 @@ int main (int argc, char **argv) } return set_user_info (bdef, user_name, full_name, home_dir, + acct_desc, home_drive, logon_script, profile_path, account_control, |