summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in3
-rw-r--r--source3/include/ads.h25
-rw-r--r--source3/include/includes.h2
-rw-r--r--source3/lib/netapi/examples/Makefile.in14
-rw-r--r--source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c43
-rw-r--r--source3/lib/netapi/examples/netdomjoin/netdomjoin.c4
-rw-r--r--source3/lib/netapi/examples/share/share_add.c110
-rw-r--r--source3/lib/netapi/examples/user/user_getgroups.c133
-rw-r--r--source3/lib/netapi/examples/user/user_getinfo.c149
-rw-r--r--source3/lib/netapi/examples/user/user_setinfo.c122
-rw-r--r--source3/lib/netapi/joindomain.c2
-rw-r--r--source3/lib/netapi/libnetapi.c98
-rw-r--r--source3/lib/netapi/libnetapi.h19
-rw-r--r--source3/lib/netapi/netapi.h194
-rw-r--r--source3/lib/netapi/share.c133
-rw-r--r--source3/lib/netapi/user.c919
-rw-r--r--source3/libads/kerberos_keytab.c11
-rw-r--r--source3/libnet/libnet_join.c27
-rw-r--r--source3/libnet/libnet_keytab.c40
-rw-r--r--source3/librpc/gen_ndr/libnetapi.h92
-rw-r--r--source3/librpc/gen_ndr/ndr_libnetapi.c251
-rw-r--r--source3/librpc/gen_ndr/ndr_libnetapi.h69
-rw-r--r--source3/librpc/idl/libnetapi.idl95
-rw-r--r--source3/libsmb/clikrb5.c32
-rw-r--r--source3/nsswitch/libwbclient/wbc_pam.c271
-rw-r--r--source3/nsswitch/libwbclient/wbclient.c2
-rw-r--r--source3/nsswitch/libwbclient/wbclient.h78
-rw-r--r--source3/nsswitch/wbinfo.c34
-rw-r--r--source3/utils/net_dom.c8
-rw-r--r--source3/utils/net_rpc.c492
-rw-r--r--source3/utils/net_rpc_shell.c9
31 files changed, 2718 insertions, 763 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 486d47f5f8..5793b5ef4d 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -1835,7 +1835,8 @@ LIBNETAPI_OBJ0 = lib/netapi/netapi.o \
lib/netapi/group.o \
lib/netapi/localgroup.o \
lib/netapi/samr.o \
- lib/netapi/sid.o
+ lib/netapi/sid.o \
+ lib/netapi/share.o
LIBNETAPI_OBJ = $(LIBNETAPI_OBJ0) $(LIBNET_OBJ) \
$(LIBSMBCONF_OBJ) \
diff --git a/source3/include/ads.h b/source3/include/ads.h
index 0d464b2d81..97faf0b6eb 100644
--- a/source3/include/ads.h
+++ b/source3/include/ads.h
@@ -372,9 +372,30 @@ typedef struct {
krb5_addresses *addrs;
#else
#error UNKNOWN_KRB5_ADDRESS_TYPE
-#endif
+#endif /* defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) */
} smb_krb5_addresses;
-#endif
+
+#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE /* Heimdal */
+#define KRB5_KEY_TYPE(k) ((k)->keytype)
+#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length)
+#define KRB5_KEY_DATA(k) ((k)->keyvalue.data)
+#define KRB5_KEY_DATA_CAST void
+#else /* MIT */
+#define KRB5_KEY_TYPE(k) ((k)->enctype)
+#define KRB5_KEY_LENGTH(k) ((k)->length)
+#define KRB5_KEY_DATA(k) ((k)->contents)
+#define KRB5_KEY_DATA_CAST krb5_octet
+#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */
+
+#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */
+#define KRB5_KT_KEY(k) (&(k)->key)
+#elif HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */
+#define KRB5_KT_KEY(k) (&(k)->keyblock)
+#else
+#error krb5_keytab_entry has no key or keyblock member
+#endif /* HAVE_KRB5_KEYTAB_ENTRY_KEY */
+
+#endif /* HAVE_KRB5 */
enum ads_extended_dn_flags {
ADS_EXTENDED_DN_HEX_STRING = 0,
diff --git a/source3/include/includes.h b/source3/include/includes.h
index fa385cba2a..958e7cba1f 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -1234,7 +1234,7 @@ krb5_error_code smb_krb5_mk_error(krb5_context context,
krb5_error_code error_code,
const krb5_principal server,
krb5_data *reply);
-krb5_enctype smb_get_enctype_from_kt_entry(const krb5_keytab_entry *kt_entry);
+krb5_enctype smb_get_enctype_from_kt_entry(krb5_keytab_entry *kt_entry);
krb5_error_code smb_krb5_enctype_to_string(krb5_context context,
krb5_enctype enctype,
char **etype_s);
diff --git a/source3/lib/netapi/examples/Makefile.in b/source3/lib/netapi/examples/Makefile.in
index 0b7553c389..d48457a694 100644
--- a/source3/lib/netapi/examples/Makefile.in
+++ b/source3/lib/netapi/examples/Makefile.in
@@ -31,6 +31,7 @@ PROGS = bin/getdc@EXEEXT@ \
bin/user_setinfo@EXEEXT@ \
bin/user_modalsget@EXEEXT@ \
bin/user_modalsset@EXEEXT@ \
+ bin/user_getgroups@EXEEXT@ \
bin/group_add@EXEEXT@ \
bin/group_del@EXEEXT@ \
bin/group_enum@EXEEXT@ \
@@ -48,7 +49,8 @@ PROGS = bin/getdc@EXEEXT@ \
bin/localgroup_delmembers@EXEEXT@ \
bin/localgroup_setmembers@EXEEXT@ \
bin/localgroup_getmembers@EXEEXT@ \
- bin/remote_tod@EXEEXT@
+ bin/remote_tod@EXEEXT@ \
+ bin/share_add@EXEEXT@
all: $(PROGS)
@@ -91,6 +93,7 @@ USERGETINFO_OBJ = user/user_getinfo.o $(CMDLINE_OBJ)
USERSETINFO_OBJ = user/user_setinfo.o $(CMDLINE_OBJ)
USERMODALSGET_OBJ = user/user_modalsget.o $(CMDLINE_OBJ)
USERMODALSSET_OBJ = user/user_modalsset.o $(CMDLINE_OBJ)
+USERGETGROUPS_OBJ = user/user_getgroups.o $(CMDLINE_OBJ)
GROUPADD_OBJ = group/group_add.o $(CMDLINE_OBJ)
GROUPDEL_OBJ = group/group_del.o $(CMDLINE_OBJ)
GROUPENUM_OBJ = group/group_enum.o $(CMDLINE_OBJ)
@@ -109,6 +112,7 @@ LOCALGROUPDELMEMBERS_OBJ = localgroup/localgroup_delmembers.o $(CMDLINE_OBJ)
LOCALGROUPSETMEMBERS_OBJ = localgroup/localgroup_setmembers.o $(CMDLINE_OBJ)
LOCALGROUPGETMEMBERS_OBJ = localgroup/localgroup_getmembers.o $(CMDLINE_OBJ)
REMOTETOD_OBJ = server/remote_tod.o $(CMDLINE_OBJ)
+SHAREADD_OBJ = share/share_add.o $(CMDLINE_OBJ)
bin/getdc@EXEEXT@: $(BINARY_PREREQS) $(GETDC_OBJ)
@echo Linking $@
@@ -166,6 +170,10 @@ bin/user_modalsset@EXEEXT@: $(BINARY_PREREQS) $(USERMODALSSET_OBJ)
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(USERMODALSSET_OBJ) $(LDFLAGS) $(DYNEXP) $(CMDLINE_LIBS)
+bin/user_getgroups@EXEEXT@: $(BINARY_PREREQS) $(USERGETGROUPS_OBJ)
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(USERGETGROUPS_OBJ) $(LDFLAGS) $(DYNEXP) $(CMDLINE_LIBS)
+
bin/group_add@EXEEXT@: $(BINARY_PREREQS) $(GROUPADD_OBJ)
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(GROUPADD_OBJ) $(LDFLAGS) $(DYNEXP) $(CMDLINE_LIBS)
@@ -238,6 +246,10 @@ bin/remote_tod@EXEEXT@: $(BINARY_PREREQS) $(REMOTETOD_OBJ)
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(REMOTETOD_OBJ) $(LDFLAGS) $(DYNEXP) $(CMDLINE_LIBS)
+bin/share_add@EXEEXT@: $(BINARY_PREREQS) $(SHAREADD_OBJ)
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(SHAREADD_OBJ) $(LDFLAGS) $(DYNEXP) $(CMDLINE_LIBS)
+
clean:
-rm -f $(PROGS)
-rm -f core */*~ *~ \
diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c
index 418b9c8b8e..4e0488ed59 100644
--- a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c
+++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c
@@ -38,11 +38,6 @@
#define SAMBA_IMAGE_PATH "/usr/share/pixmaps/samba/logo.png"
#define SAMBA_IMAGE_PATH_SMALL "/usr/share/pixmaps/samba/logo-small.png"
-#define WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED ( 0x00000020 )
-#define WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE ( 0x00000004 )
-#define WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE ( 0x00000002 )
-#define WKSSVC_JOIN_FLAGS_JOIN_TYPE ( 0x00000001 )
-
#define NetSetupWorkgroupName ( 2 )
#define NetSetupDomainName ( 3 )
@@ -631,9 +626,9 @@ static void callback_do_join(GtkWidget *widget,
if (state->name_type_new == NetSetupDomainName) {
domain_join = TRUE;
join_creds_required = TRUE;
- join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
- WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
- WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED; /* for testing */
+ join_flags = NETSETUP_JOIN_DOMAIN |
+ NETSETUP_ACCT_CREATE |
+ NETSETUP_DOMAIN_JOIN_IF_JOINED; /* for testing */
}
if ((state->name_type_initial == NetSetupDomainName) &&
@@ -641,8 +636,8 @@ static void callback_do_join(GtkWidget *widget,
try_unjoin = TRUE;
unjoin_creds_required = TRUE;
join_creds_required = FALSE;
- unjoin_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
- WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE;
+ unjoin_flags = NETSETUP_JOIN_DOMAIN |
+ NETSETUP_ACCT_DELETE;
}
if (try_unjoin) {
@@ -823,9 +818,13 @@ static void callback_enter_hostname_and_unlock(GtkWidget *widget,
}
state->hostname_changed = TRUE;
if (state->name_type_initial == NetSetupDomainName) {
- asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain);
+ if (asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain) == -1) {
+ return;
+ }
} else {
- asprintf(&str, "%s.", entry_text);
+ if (asprintf(&str, "%s.", entry_text) == -1) {
+ return;
+ }
}
gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str);
free(str);
@@ -1132,10 +1131,14 @@ static void callback_do_change(GtkWidget *widget,
char *str = NULL;
entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
if (state->name_type_initial == NetSetupDomainName) {
- asprintf(&str, "%s.%s", entry_text,
- state->my_dnsdomain);
+ if (asprintf(&str, "%s.%s", entry_text,
+ state->my_dnsdomain) == -1) {
+ return;
+ }
} else {
- asprintf(&str, "%s.", entry_text);
+ if (asprintf(&str, "%s.", entry_text) == -1) {
+ return;
+ }
}
gtk_label_set_text(GTK_LABEL(state->label_full_computer_name),
str);
@@ -1436,10 +1439,14 @@ static int draw_main_window(struct join_state *state)
/* Label */
char *str = NULL;
if (state->name_type_initial == NetSetupDomainName) {
- asprintf(&str, "%s.%s", state->my_hostname,
- state->my_dnsdomain);
+ if (asprintf(&str, "%s.%s", state->my_hostname,
+ state->my_dnsdomain) == -1) {
+ return -1;
+ }
} else {
- asprintf(&str, "%s.", state->my_hostname);
+ if (asprintf(&str, "%s.", state->my_hostname) == -1) {
+ return -1;
+ }
}
label = gtk_label_new(str);
diff --git a/source3/lib/netapi/examples/netdomjoin/netdomjoin.c b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c
index bd7c36382a..08ce71b938 100644
--- a/source3/lib/netapi/examples/netdomjoin/netdomjoin.c
+++ b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c
@@ -39,7 +39,9 @@ int main(int argc, const char **argv)
const char *account_ou = NULL;
const char *account = NULL;
const char *password = NULL;
- uint32_t join_flags = 0x00000023;
+ uint32_t join_flags = NETSETUP_JOIN_DOMAIN |
+ NETSETUP_ACCT_CREATE |
+ NETSETUP_DOMAIN_JOIN_IF_JOINED;
struct libnetapi_ctx *ctx = NULL;
poptContext pc;
diff --git a/source3/lib/netapi/examples/share/share_add.c b/source3/lib/netapi/examples/share/share_add.c
new file mode 100644
index 0000000000..3d7948840d
--- /dev/null
+++ b/source3/lib/netapi/examples/share/share_add.c
@@ -0,0 +1,110 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetShareAdd query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *sharename = NULL;
+ const char *path = NULL;
+ uint32_t level = 0;
+ uint32_t parm_err = 0;
+
+ struct SHARE_INFO_2 i2;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("share_add", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname sharename path");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ sharename = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ path = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetShareAdd */
+
+ i2.shi2_netname = sharename;
+ i2.shi2_type = 0;
+ i2.shi2_remark = "Test share created via NetApi";
+ i2.shi2_permissions = 0;
+ i2.shi2_max_uses = (uint32_t)-1;
+ i2.shi2_current_uses = 0;
+ i2.shi2_path = path;
+ i2.shi2_passwd = NULL;
+
+ status = NetShareAdd(hostname,
+ 2,
+ (uint8_t *)&i2,
+ &parm_err);
+ if (status != 0) {
+ printf("NetShareAdd failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_getgroups.c b/source3/lib/netapi/examples/user/user_getgroups.c
new file mode 100644
index 0000000000..939415e0eb
--- /dev/null
+++ b/source3/lib/netapi/examples/user/user_getgroups.c
@@ -0,0 +1,133 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetUserGetGroups query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *username = NULL;
+ uint32_t level = 0;
+ uint8_t *buffer = NULL;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ int i;
+
+ struct GROUP_USERS_INFO_0 *info0 = NULL;
+ struct GROUP_USERS_INFO_1 *info1 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("user_getgroups", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname username level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ username = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetUserGetGroups */
+
+ do {
+ status = NetUserGetGroups(hostname,
+ username,
+ level,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+
+ switch (level) {
+ case 0:
+ info0 = (struct GROUP_USERS_INFO_0 *)buffer;
+ break;
+ case 1:
+ info1 = (struct GROUP_USERS_INFO_1 *)buffer;
+ break;
+ default:
+ break;
+ }
+
+ for (i=0; i<entries_read; i++) {
+ switch (level) {
+ case 0:
+ printf("#%d group: %s\n", i, info0->grui0_name);
+ info0++;
+ break;
+ case 1:
+ printf("#%d group: %s\n", i, info1->grui1_name);
+ printf("#%d attributes: %d\n", i, info1->grui1_attributes);
+ info1++;
+ break;
+ default:
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status != 0) {
+ printf("NetUserGetGroups failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_getinfo.c b/source3/lib/netapi/examples/user/user_getinfo.c
index 19234d0532..9e95260b5a 100644
--- a/source3/lib/netapi/examples/user/user_getinfo.c
+++ b/source3/lib/netapi/examples/user/user_getinfo.c
@@ -36,10 +36,15 @@ int main(int argc, const char **argv)
uint8_t *buffer = NULL;
uint32_t level = 0;
char *sid_str = NULL;
+ int i;
struct USER_INFO_0 *u0;
struct USER_INFO_1 *u1;
+ struct USER_INFO_2 *u2;
+ struct USER_INFO_3 *u3;
+ struct USER_INFO_4 *u4;
struct USER_INFO_10 *u10;
+ struct USER_INFO_11 *u11;
struct USER_INFO_20 *u20;
struct USER_INFO_23 *u23;
@@ -107,6 +112,121 @@ int main(int argc, const char **argv)
printf("flags: 0x%08x\n", u1->usri1_flags);
printf("script: %s\n", u1->usri1_script_path);
break;
+ case 2:
+ u2 = (struct USER_INFO_2 *)buffer;
+ printf("name: %s\n", u2->usri2_name);
+ printf("password: %s\n", u2->usri2_password);
+ printf("password_age: %d\n", u2->usri2_password_age);
+ printf("priv: %d\n", u2->usri2_priv);
+ printf("homedir: %s\n", u2->usri2_home_dir);
+ printf("comment: %s\n", u2->usri2_comment);
+ printf("flags: 0x%08x\n", u2->usri2_flags);
+ printf("script: %s\n", u2->usri2_script_path);
+ printf("auth flags: 0x%08x\n", u2->usri2_auth_flags);
+ printf("full name: %s\n", u2->usri2_full_name);
+ printf("user comment: %s\n", u2->usri2_usr_comment);
+ printf("user parameters: %s\n", u2->usri2_parms);
+ printf("workstations: %s\n", u2->usri2_workstations);
+ printf("last logon (seconds since jan. 1, 1970 GMT): %d\n",
+ u2->usri2_last_logon);
+ printf("last logoff (seconds since jan. 1, 1970 GMT): %d\n",
+ u2->usri2_last_logoff);
+ printf("account expires (seconds since jan. 1, 1970 GMT): %d\n",
+ u2->usri2_acct_expires);
+ printf("max storage: %d\n", u2->usri2_max_storage);
+ printf("units per week: %d\n", u2->usri2_units_per_week);
+ printf("logon hours:");
+ for (i=0; i<21; i++) {
+ printf(" %x", (uint8_t)u2->usri2_logon_hours[i]);
+ }
+ printf("\n");
+ printf("bad password count: %d\n", u2->usri2_bad_pw_count);
+ printf("logon count: %d\n", u2->usri2_num_logons);
+ printf("logon server: %s\n", u2->usri2_logon_server);
+ printf("country code: %d\n", u2->usri2_country_code);
+ printf("code page: %d\n", u2->usri2_code_page);
+ break;
+ case 3:
+ u3 = (struct USER_INFO_3 *)buffer;
+ printf("name: %s\n", u3->usri3_name);
+ printf("password_age: %d\n", u3->usri3_password_age);
+ printf("priv: %d\n", u3->usri3_priv);
+ printf("homedir: %s\n", u3->usri3_home_dir);
+ printf("comment: %s\n", u3->usri3_comment);
+ printf("flags: 0x%08x\n", u3->usri3_flags);
+ printf("script: %s\n", u3->usri3_script_path);
+ printf("auth flags: 0x%08x\n", u3->usri3_auth_flags);
+ printf("full name: %s\n", u3->usri3_full_name);
+ printf("user comment: %s\n", u3->usri3_usr_comment);
+ printf("user parameters: %s\n", u3->usri3_parms);
+ printf("workstations: %s\n", u3->usri3_workstations);
+ printf("last logon (seconds since jan. 1, 1970 GMT): %d\n",
+ u3->usri3_last_logon);
+ printf("last logoff (seconds since jan. 1, 1970 GMT): %d\n",
+ u3->usri3_last_logoff);
+ printf("account expires (seconds since jan. 1, 1970 GMT): %d\n",
+ u3->usri3_acct_expires);
+ printf("max storage: %d\n", u3->usri3_max_storage);
+ printf("units per week: %d\n", u3->usri3_units_per_week);
+ printf("logon hours:");
+ for (i=0; i<21; i++) {
+ printf(" %x", (uint8_t)u3->usri3_logon_hours[i]);
+ }
+ printf("\n");
+ printf("bad password count: %d\n", u3->usri3_bad_pw_count);
+ printf("logon count: %d\n", u3->usri3_num_logons);
+ printf("logon server: %s\n", u3->usri3_logon_server);
+ printf("country code: %d\n", u3->usri3_country_code);
+ printf("code page: %d\n", u3->usri3_code_page);
+ printf("user id: %d\n", u3->usri3_user_id);
+ printf("primary group id: %d\n", u3->usri3_primary_group_id);
+ printf("profile: %s\n", u3->usri3_profile);
+ printf("home dir drive: %s\n", u3->usri3_home_dir_drive);
+ printf("password expired: %d\n", u3->usri3_password_expired);
+ break;
+ case 4:
+ u4 = (struct USER_INFO_4 *)buffer;
+ printf("name: %s\n", u4->usri4_name);
+ printf("password: %s\n", u4->usri4_password);
+ printf("password_age: %d\n", u4->usri4_password_age);
+ printf("priv: %d\n", u4->usri4_priv);
+ printf("homedir: %s\n", u4->usri4_home_dir);
+ printf("comment: %s\n", u4->usri4_comment);
+ printf("flags: 0x%08x\n", u4->usri4_flags);
+ printf("script: %s\n", u4->usri4_script_path);
+ printf("auth flags: 0x%08x\n", u4->usri4_auth_flags);
+ printf("full name: %s\n", u4->usri4_full_name);
+ printf("user comment: %s\n", u4->usri4_usr_comment);
+ printf("user parameters: %s\n", u4->usri4_parms);
+ printf("workstations: %s\n", u4->usri4_workstations);
+ printf("last logon (seconds since jan. 1, 1970 GMT): %d\n",
+ u4->usri4_last_logon);
+ printf("last logoff (seconds since jan. 1, 1970 GMT): %d\n",
+ u4->usri4_last_logoff);
+ printf("account expires (seconds since jan. 1, 1970 GMT): %d\n",
+ u4->usri4_acct_expires);
+ printf("max storage: %d\n", u4->usri4_max_storage);
+ printf("units per week: %d\n", u4->usri4_units_per_week);
+ printf("logon hours:");
+ for (i=0; i<21; i++) {
+ printf(" %x", (uint8_t)u4->usri4_logon_hours[i]);
+ }
+ printf("\n");
+ printf("bad password count: %d\n", u4->usri4_bad_pw_count);
+ printf("logon count: %d\n", u4->usri4_num_logons);
+ printf("logon server: %s\n", u4->usri4_logon_server);
+ printf("country code: %d\n", u4->usri4_country_code);
+ printf("code page: %d\n", u4->usri4_code_page);
+ if (ConvertSidToStringSid(u4->usri4_user_sid,
+ &sid_str)) {
+ printf("user_sid: %s\n", sid_str);
+ free(sid_str);
+ }
+ printf("primary group id: %d\n", u4->usri4_primary_group_id);
+ printf("profile: %s\n", u4->usri4_profile);
+ printf("home dir drive: %s\n", u4->usri4_home_dir_drive);
+ printf("password expired: %d\n", u4->usri4_password_expired);
+ break;
case 10:
u10 = (struct USER_INFO_10 *)buffer;
printf("name: %s\n", u10->usri10_name);
@@ -114,6 +234,35 @@ int main(int argc, const char **argv)
printf("usr_comment: %s\n", u10->usri10_usr_comment);
printf("full_name: %s\n", u10->usri10_full_name);
break;
+ case 11:
+ u11 = (struct USER_INFO_11 *)buffer;
+ printf("name: %s\n", u11->usri11_name);
+ printf("comment: %s\n", u11->usri11_comment);
+ printf("user comment: %s\n", u11->usri11_usr_comment);
+ printf("full name: %s\n", u11->usri11_full_name);
+ printf("priv: %d\n", u11->usri11_priv);
+ printf("auth flags: 0x%08x\n", u11->usri11_auth_flags);
+ printf("password_age: %d\n", u11->usri11_password_age);
+ printf("homedir: %s\n", u11->usri11_home_dir);
+ printf("user parameters: %s\n", u11->usri11_parms);
+ printf("last logon (seconds since jan. 1, 1970 GMT): %d\n",
+ u11->usri11_last_logon);
+ printf("last logoff (seconds since jan. 1, 1970 GMT): %d\n",
+ u11->usri11_last_logoff);
+ printf("bad password count: %d\n", u11->usri11_bad_pw_count);
+ printf("logon count: %d\n", u11->usri11_num_logons);
+ printf("logon server: %s\n", u11->usri11_logon_server);
+ printf("country code: %d\n", u11->usri11_country_code);
+ printf("workstations: %s\n", u11->usri11_workstations);
+ printf("max storage: %d\n", u11->usri11_max_storage);
+ printf("units per week: %d\n", u11->usri11_units_per_week);
+ printf("logon hours:");
+ for (i=0; i<21; i++) {
+ printf(" %x", (uint8_t)u11->usri11_logon_hours[i]);
+ }
+ printf("\n");
+ printf("code page: %d\n", u11->usri11_code_page);
+ break;
case 20:
u20 = (struct USER_INFO_20 *)buffer;
printf("name: %s\n", u20->usri20_name);
diff --git a/source3/lib/netapi/examples/user/user_setinfo.c b/source3/lib/netapi/examples/user/user_setinfo.c
index ec464232e9..4f02ae7781 100644
--- a/source3/lib/netapi/examples/user/user_setinfo.c
+++ b/source3/lib/netapi/examples/user/user_setinfo.c
@@ -33,10 +33,34 @@ int main(int argc, const char **argv)
struct libnetapi_ctx *ctx = NULL;
const char *hostname = NULL;
const char *username = NULL;
- uint32_t level = 1007;
+ uint32_t level = 0;
uint32_t parm_err = 0;
-
+ uint8_t *buffer = NULL;
+ const char *val = NULL;
+
+ struct USER_INFO_0 u0;
+ struct USER_INFO_1 u1;
+ struct USER_INFO_2 u2;
+ struct USER_INFO_3 u3;
+ struct USER_INFO_4 u4;
+ struct USER_INFO_21 u21;
+ struct USER_INFO_22 u22;
+ struct USER_INFO_1003 u1003;
+ struct USER_INFO_1005 u1005;
+ struct USER_INFO_1006 u1006;
struct USER_INFO_1007 u1007;
+ struct USER_INFO_1008 u1008;
+ struct USER_INFO_1009 u1009;
+ struct USER_INFO_1010 u1010;
+ struct USER_INFO_1011 u1011;
+ struct USER_INFO_1012 u1012;
+ struct USER_INFO_1014 u1014;
+ struct USER_INFO_1017 u1017;
+ struct USER_INFO_1020 u1020;
+ struct USER_INFO_1024 u1024;
+ struct USER_INFO_1051 u1051;
+ struct USER_INFO_1052 u1052;
+ struct USER_INFO_1053 u1053;
poptContext pc;
int opt;
@@ -70,18 +94,104 @@ int main(int argc, const char **argv)
}
username = poptGetArg(pc);
- if (poptPeekArg(pc)) {
- level = atoi(poptGetArg(pc));
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ level = atoi(poptGetArg(pc));
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
}
+ val = poptGetArg(pc);
/* NetUserSetInfo */
- u1007.usri1007_comment = "NetApi test comment";
+ switch (level) {
+ case 0:
+ u0.usri0_name = val;
+ buffer = (uint8_t *)&u0;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ case 21:
+ break;
+ case 22:
+ break;
+ case 1003:
+ u1003.usri1003_password = val;
+ buffer = (uint8_t *)&u1003;
+ break;
+ case 1005:
+ u1005.usri1005_priv = atoi(val);
+ buffer = (uint8_t *)&u1005;
+ break;
+ case 1006:
+ u1006.usri1006_home_dir = val;
+ buffer = (uint8_t *)&u1006;
+ break;
+ case 1007:
+ u1007.usri1007_comment = val;
+ buffer = (uint8_t *)&u1007;
+ break;
+ case 1008:
+ u1008.usri1008_flags = atoi(val);
+ buffer = (uint8_t *)&u1008;
+ break;
+ case 1009:
+ u1009.usri1009_script_path = val;
+ buffer = (uint8_t *)&u1009;
+ break;
+ case 1010:
+ u1010.usri1010_auth_flags = atoi(val);
+ buffer = (uint8_t *)&u1010;
+ break;
+ case 1011:
+ u1011.usri1011_full_name = val;
+ buffer = (uint8_t *)&u1011;
+ break;
+ case 1012:
+ u1012.usri1012_usr_comment = val;
+ buffer = (uint8_t *)&u1012;
+ break;
+ case 1014:
+ u1014.usri1014_workstations = val;
+ buffer = (uint8_t *)&u1014;
+ break;
+ case 1017:
+ u1017.usri1017_acct_expires = atoi(val);
+ buffer = (uint8_t *)&u1017;
+ break;
+ case 1020:
+ break;
+ case 1024:
+ u1024.usri1024_country_code = atoi(val);
+ buffer = (uint8_t *)&u1024;
+ break;
+ case 1051:
+ u1051.usri1051_primary_group_id = atoi(val);
+ buffer = (uint8_t *)&u1051;
+ break;
+ case 1052:
+ u1052.usri1052_profile = val;
+ buffer = (uint8_t *)&u1052;
+ break;
+ case 1053:
+ u1053.usri1053_home_dir_drive = val;
+ buffer = (uint8_t *)&u1053;
+ break;
+ default:
+ break;
+ }
status = NetUserSetInfo(hostname,
username,
level,
- (uint8_t *)&u1007,
+ buffer,
&parm_err);
if (status != 0) {
printf("NetUserSetInfo failed with: %s\n",
diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c
index 2a6fc80ca3..17ea3923fe 100644
--- a/source3/lib/netapi/joindomain.c
+++ b/source3/lib/netapi/joindomain.c
@@ -364,7 +364,7 @@ WERROR NetGetJoinableOUs_l(struct libnetapi_ctx *ctx,
dc = strip_hostname(info->dc_unc);
- ads = ads_init(r->in.domain, r->in.domain, dc);
+ ads = ads_init(info->domain_name, info->domain_name, dc);
if (!ads) {
return WERR_GENERAL_FAILURE;
}
diff --git a/source3/lib/netapi/libnetapi.c b/source3/lib/netapi/libnetapi.c
index 5fe48077a8..b4f2bb6ac2 100644
--- a/source3/lib/netapi/libnetapi.c
+++ b/source3/lib/netapi/libnetapi.c
@@ -726,6 +726,58 @@ NET_API_STATUS NetUserSetInfo(const char * server_name /* [in] */,
}
/****************************************************************
+ NetUserGetGroups
+****************************************************************/
+
+NET_API_STATUS NetUserGetGroups(const char * server_name /* [in] */,
+ const char * user_name /* [in] */,
+ uint32_t level /* [in] */,
+ uint8_t **buffer /* [out] [ref] */,
+ uint32_t prefmaxlen /* [in] */,
+ uint32_t *entries_read /* [out] [ref] */,
+ uint32_t *total_entries /* [out] [ref] */)
+{
+ struct NetUserGetGroups r;
+ struct libnetapi_ctx *ctx = NULL;
+ NET_API_STATUS status;
+ WERROR werr;
+
+ status = libnetapi_getctx(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ /* In parameters */
+ r.in.server_name = server_name;
+ r.in.user_name = user_name;
+ r.in.level = level;
+ r.in.prefmaxlen = prefmaxlen;
+
+ /* Out parameters */
+ r.out.buffer = buffer;
+ r.out.entries_read = entries_read;
+ r.out.total_entries = total_entries;
+
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_IN_DEBUG(NetUserGetGroups, &r);
+ }
+
+ if (LIBNETAPI_LOCAL_SERVER(server_name)) {
+ werr = NetUserGetGroups_l(ctx, &r);
+ } else {
+ werr = NetUserGetGroups_r(ctx, &r);
+ }
+
+ r.out.result = W_ERROR_V(werr);
+
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_OUT_DEBUG(NetUserGetGroups, &r);
+ }
+
+ return r.out.result;
+}
+
+/****************************************************************
NetUserModalsGet
****************************************************************/
@@ -1721,3 +1773,49 @@ NET_API_STATUS NetRemoteTOD(const char * server_name /* [in] */,
return r.out.result;
}
+/****************************************************************
+ NetShareAdd
+****************************************************************/
+
+NET_API_STATUS NetShareAdd(const char * server_name /* [in] */,
+ uint32_t level /* [in] */,
+ uint8_t *buffer /* [in] [ref] */,
+ uint32_t *parm_err /* [out] [ref] */)
+{
+ struct NetShareAdd r;
+ struct libnetapi_ctx *ctx = NULL;
+ NET_API_STATUS status;
+ WERROR werr;
+
+ status = libnetapi_getctx(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ /* In parameters */
+ r.in.server_name = server_name;
+ r.in.level = level;
+ r.in.buffer = buffer;
+
+ /* Out parameters */
+ r.out.parm_err = parm_err;
+
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_IN_DEBUG(NetShareAdd, &r);
+ }
+
+ if (LIBNETAPI_LOCAL_SERVER(server_name)) {
+ werr = NetShareAdd_l(ctx, &r);
+ } else {
+ werr = NetShareAdd_r(ctx, &r);
+ }
+
+ r.out.result = W_ERROR_V(werr);
+
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_OUT_DEBUG(NetShareAdd, &r);
+ }
+
+ return r.out.result;
+}
+
diff --git a/source3/lib/netapi/libnetapi.h b/source3/lib/netapi/libnetapi.h
index b0ff8e5baf..9a75b396fe 100644
--- a/source3/lib/netapi/libnetapi.h
+++ b/source3/lib/netapi/libnetapi.h
@@ -125,6 +125,17 @@ WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
struct NetUserSetInfo *r);
WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
struct NetUserSetInfo *r);
+NET_API_STATUS NetUserGetGroups(const char * server_name /* [in] */,
+ const char * user_name /* [in] */,
+ uint32_t level /* [in] */,
+ uint8_t **buffer /* [out] [ref] */,
+ uint32_t prefmaxlen /* [in] */,
+ uint32_t *entries_read /* [out] [ref] */,
+ uint32_t *total_entries /* [out] [ref] */);
+WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
+ struct NetUserGetGroups *r);
+WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
+ struct NetUserGetGroups *r);
NET_API_STATUS NetUserModalsGet(const char * server_name /* [in] */,
uint32_t level /* [in] */,
uint8_t **buffer /* [out] [ref] */);
@@ -306,4 +317,12 @@ WERROR NetRemoteTOD_r(struct libnetapi_ctx *ctx,
struct NetRemoteTOD *r);
WERROR NetRemoteTOD_l(struct libnetapi_ctx *ctx,
struct NetRemoteTOD *r);
+NET_API_STATUS NetShareAdd(const char * server_name /* [in] */,
+ uint32_t level /* [in] */,
+ uint8_t *buffer /* [in] [ref] */,
+ uint32_t *parm_err /* [out] [ref] */);
+WERROR NetShareAdd_r(struct libnetapi_ctx *ctx,
+ struct NetShareAdd *r);
+WERROR NetShareAdd_l(struct libnetapi_ctx *ctx,
+ struct NetShareAdd *r);
#endif /* __LIBNETAPI_LIBNETAPI__ */
diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h
index f7bf1880cc..05c702cb3f 100644
--- a/source3/lib/netapi/netapi.h
+++ b/source3/lib/netapi/netapi.h
@@ -33,6 +33,8 @@ typedef enum {
#define ERROR_MORE_DATA ( 234L )
+#define ENCRYPTED_PWLEN ( 16 )
+
/****************************************************************
****************************************************************/
@@ -73,6 +75,20 @@ struct DOMAIN_CONTROLLER_INFO {
const char * client_site_name;
};
+/* bitmap NetJoinFlags */
+#define NETSETUP_JOIN_DOMAIN ( 0x00000001 )
+#define NETSETUP_ACCT_CREATE ( 0x00000002 )
+#define NETSETUP_ACCT_DELETE ( 0x00000004 )
+#define NETSETUP_WIN9X_UPGRADE ( 0x00000010 )
+#define NETSETUP_DOMAIN_JOIN_IF_JOINED ( 0x00000020 )
+#define NETSETUP_JOIN_UNSECURE ( 0x00000040 )
+#define NETSETUP_MACHINE_PWD_PASSED ( 0x00000080 )
+#define NETSETUP_DEFER_SPN_SET ( 0x00000100 )
+#define NETSETUP_JOIN_DC_ACCOUNT ( 0x00000200 )
+#define NETSETUP_JOIN_WITH_NEW_NAME ( 0x00000400 )
+#define NETSETUP_INSTALL_INVOCATION ( 0x00040000 )
+#define NETSETUP_IGNORE_UNSUPPORTED_FLAGS ( 0x10000000 )
+
#define FILTER_TEMP_DUPLICATE_ACCOUNT ( 0x0001 )
#define FILTER_NORMAL_ACCOUNT ( 0x0002 )
#define FILTER_INTERDOMAIN_TRUST_ACCOUNT ( 0x0008 )
@@ -89,6 +105,10 @@ struct USER_INFO_0 {
const char * usri0_name;
};
+#define USER_PRIV_GUEST ( 0 )
+#define USER_PRIV_USER ( 1 )
+#define USER_PRIV_ADMIN ( 2 )
+
struct USER_INFO_1 {
const char * usri1_name;
const char * usri1_password;
@@ -100,6 +120,11 @@ struct USER_INFO_1 {
const char * usri1_script_path;
};
+#define AF_OP_PRINT ( 0x1 )
+#define AF_OP_COMM ( 0x2 )
+#define AF_OP_SERVER ( 0x4 )
+#define AF_OP_ACCOUNTS ( 0x8 )
+
struct USER_INFO_2 {
const char * usri2_name;
const char * usri2_password;
@@ -183,7 +208,7 @@ struct USER_INFO_4 {
const char * usri4_logon_server;
uint32_t usri4_country_code;
uint32_t usri4_code_page;
- struct dom_sid *usri4_user_sid;/* [unique] */
+ struct domsid *usri4_user_sid;/* [unique] */
uint32_t usri4_primary_group_id;
const char * usri4_profile;
const char * usri4_home_dir_drive;
@@ -228,6 +253,37 @@ struct USER_INFO_20 {
uint32_t usri20_user_id;
};
+struct USER_INFO_21 {
+ uint8_t *usri21_password;
+};
+
+struct USER_INFO_22 {
+ const char * usri22_name;
+ uint8_t *usri22_password;
+ uint32_t usri22_password_age;
+ uint32_t usri22_priv;
+ const char * usri22_home_dir;
+ const char * usri22_comment;
+ uint32_t usri22_flags;
+ uint32_t usri22_script_path;
+ uint32_t usri22_auth_flags;
+ const char * usri22_full_name;
+ const char * usri22_usr_comment;
+ const char * usri22_parms;
+ const char * usri22_workstations;
+ uint32_t usri22_last_logon;
+ uint32_t usri22_last_logoff;
+ uint32_t usri22_acct_expires;
+ uint32_t usri22_max_storage;
+ uint32_t usri22_units_per_week;
+ uint8_t *usri22_logon_hours;/* [unique] */
+ uint32_t usri22_bad_pw_count;
+ uint32_t usri22_num_logons;
+ const char * usri22_logon_server;
+ uint32_t usri22_country_code;
+ uint32_t usri22_code_page;
+};
+
struct USER_INFO_23 {
const char * usri23_name;
const char * usri23_full_name;
@@ -236,10 +292,87 @@ struct USER_INFO_23 {
struct domsid *usri23_user_sid;/* [unique] */
};
+struct USER_INFO_1003 {
+ const char * usri1003_password;
+};
+
+struct USER_INFO_1005 {
+ uint32_t usri1005_priv;
+};
+
+struct USER_INFO_1006 {
+ const char * usri1006_home_dir;
+};
+
struct USER_INFO_1007 {
const char * usri1007_comment;
};
+struct USER_INFO_1008 {
+ uint32_t usri1008_flags;
+};
+
+struct USER_INFO_1009 {
+ const char * usri1009_script_path;
+};
+
+struct USER_INFO_1010 {
+ uint32_t usri1010_auth_flags;
+};
+
+struct USER_INFO_1011 {
+ const char * usri1011_full_name;
+};
+
+struct USER_INFO_1012 {
+ const char * usri1012_usr_comment;
+};
+
+struct USER_INFO_1013 {
+ const char * usri1013_parms;
+};
+
+struct USER_INFO_1014 {
+ const char * usri1014_workstations;
+};
+
+struct USER_INFO_1017 {
+ uint32_t usri1017_acct_expires;
+};
+
+struct USER_INFO_1018 {
+ uint32_t usri1018_max_storage;
+};
+
+struct USER_INFO_1020 {
+ uint32_t usri1020_units_per_week;
+ uint8_t *usri1020_logon_hours;/* [unique] */
+};
+
+struct USER_INFO_1023 {
+ const char * usri1023_logon_server;
+};
+
+struct USER_INFO_1024 {
+ uint32_t usri1024_country_code;
+};
+
+struct USER_INFO_1025 {
+ uint32_t usri1025_code_page;
+};
+
+struct USER_INFO_1051 {
+ uint32_t usri1051_primary_group_id;
+};
+
+struct USER_INFO_1052 {
+ const char * usri1052_profile;
+};
+
+struct USER_INFO_1053 {
+ const char * usri1053_home_dir_drive;
+};
+
struct USER_MODALS_INFO_0 {
uint32_t usrmod0_min_passwd_len;
uint32_t usrmod0_max_passwd_age;
@@ -418,6 +551,17 @@ struct TIME_OF_DAY_INFO {
uint32_t tod_weekday;
};
+struct SHARE_INFO_2 {
+ const char * shi2_netname;
+ uint32_t shi2_type;
+ const char * shi2_remark;
+ uint32_t shi2_permissions;
+ uint32_t shi2_max_uses;
+ uint32_t shi2_current_uses;
+ const char * shi2_path;
+ const char * shi2_passwd;
+};
+
#endif /* _HEADER_libnetapi */
/****************************************************************
@@ -890,6 +1034,33 @@ NET_API_STATUS NetUserModalsSet(const char * server_name /* [in] */,
/************************************************************//**
*
+ * NetUserGetGroups
+ *
+ * @brief Enumerate grouplist of a user on a server
+ *
+ * @param[in] server_name The server name to connect to
+ * @param[in] user_name The user name to query
+ * @param[in] level The enumeration level used for the query (Currently only
+ * level 0 is supported)
+ * @param[out] buffer The returned enumeration buffer
+ * @param[in] prefmaxlen The requested maximal buffer size
+ * @param[out] entries_read The number of returned entries
+ * @param[out] total_entries The number of total entries
+ * @return NET_API_STATUS
+ *
+ * example user/user_getgroups.c
+ ***************************************************************/
+
+NET_API_STATUS NetUserGetGroups(const char * server_name /* [in] */,
+ const char * user_name /* [in] */,
+ uint32_t level /* [in] */,
+ uint8_t **buffer /* [out] [ref] */,
+ uint32_t prefmaxlen /* [in] */,
+ uint32_t *entries_read /* [out] [ref] */,
+ uint32_t *total_entries /* [out] [ref] */);
+
+/************************************************************//**
+ *
* NetQueryDisplayInformation
*
* @brief Enumerate accounts on a server
@@ -1309,6 +1480,27 @@ NET_API_STATUS NetLocalGroupSetMembers(const char * server_name /* [in] */,
NET_API_STATUS NetRemoteTOD(const char * server_name /* [in] */,
uint8_t **buf /* [out] [ref] */);
+
+/************************************************************//**
+ *
+ * NetShareAdd
+ *
+ * @brief Add Share
+ *
+ * @param[in] server_name The server name to connect to
+ * @param[in] level The level defining the requested SHARE_INFO_X structure
+ * @param[in] buf The buffer containing a SHARE_INFO_X structure
+ * @param[out] parm_err The returned parameter error number if any
+ * @return NET_API_STATUS
+ *
+ * example share/share_add.c
+ ***************************************************************/
+
+NET_API_STATUS NetShareAdd(const char * server_name /* [in] */,
+ uint32_t level /* [in] */,
+ uint8_t *buffer /* [in] [ref] */,
+ uint32_t *parm_err /* [out] [ref] */);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/source3/lib/netapi/share.c b/source3/lib/netapi/share.c
new file mode 100644
index 0000000000..3b99a8d291
--- /dev/null
+++ b/source3/lib/netapi/share.c
@@ -0,0 +1,133 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetApi Share Support
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+
+#include "librpc/gen_ndr/libnetapi.h"
+#include "lib/netapi/netapi.h"
+#include "lib/netapi/netapi_private.h"
+#include "lib/netapi/libnetapi.h"
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS map_SHARE_INFO_buffer_to_srvsvc_share_info(TALLOC_CTX *mem_ctx,
+ uint8_t *buffer,
+ uint32_t level,
+ union srvsvc_NetShareInfo *info)
+{
+ struct SHARE_INFO_2 *i2 = NULL;
+ struct srvsvc_NetShareInfo2 *s2 = NULL;
+
+ if (!buffer) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ switch (level) {
+ case 2:
+ i2 = (struct SHARE_INFO_2 *)buffer;
+
+ s2 = TALLOC_P(mem_ctx, struct srvsvc_NetShareInfo2);
+ NT_STATUS_HAVE_NO_MEMORY(s2);
+
+ s2->name = i2->shi2_netname;
+ s2->type = i2->shi2_type;
+ s2->comment = i2->shi2_remark;
+ s2->permissions = i2->shi2_permissions;
+ s2->max_users = i2->shi2_max_uses;
+ s2->current_users = i2->shi2_current_uses;
+ s2->path = i2->shi2_path;
+ s2->password = i2->shi2_passwd;
+
+ info->info2 = s2;
+
+ break;
+ default:
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+WERROR NetShareAdd_r(struct libnetapi_ctx *ctx,
+ struct NetShareAdd *r)
+{
+ WERROR werr;
+ NTSTATUS status;
+ struct cli_state *cli = NULL;
+ struct rpc_pipe_client *pipe_cli = NULL;
+ union srvsvc_NetShareInfo info;
+
+ if (!r->in.buffer) {
+ return WERR_INVALID_PARAM;
+ }
+
+ switch (r->in.level) {
+ case 2:
+ break;
+ default:
+ return WERR_UNKNOWN_LEVEL;
+ }
+
+ werr = libnetapi_open_pipe(ctx, r->in.server_name,
+ &ndr_table_srvsvc.syntax_id,
+ &cli,
+ &pipe_cli);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
+ }
+
+ status = map_SHARE_INFO_buffer_to_srvsvc_share_info(ctx,
+ r->in.buffer,
+ r->in.level,
+ &info);
+ if (!NT_STATUS_IS_OK(status)) {
+ werr = ntstatus_to_werror(status);
+ goto done;
+ }
+
+ status = rpccli_srvsvc_NetShareAdd(pipe_cli, ctx,
+ r->in.server_name,
+ r->in.level,
+ &info,
+ r->out.parm_err,
+ &werr);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
+ }
+
+ done:
+ if (!cli) {
+ return werr;
+ }
+
+ return werr;
+}
+
+/****************************************************************
+****************************************************************/
+
+WERROR NetShareAdd_l(struct libnetapi_ctx *ctx,
+ struct NetShareAdd *r)
+{
+ LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetShareAdd);
+}
diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c
index 7b530f4308..ae8d2ecd89 100644
--- a/source3/lib/netapi/user.c
+++ b/source3/lib/netapi/user.c
@@ -30,18 +30,20 @@
static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X *infoX,
struct samr_UserInfo21 *info21)
{
- uint32_t fields_present = SAMR_FIELD_ACCT_FLAGS;
+ uint32_t fields_present = 0;
struct samr_LogonHours zero_logon_hours;
struct lsa_BinaryString zero_parameters;
- uint32_t acct_flags = 0;
NTTIME password_age;
ZERO_STRUCTP(info21);
ZERO_STRUCT(zero_logon_hours);
ZERO_STRUCT(zero_parameters);
+ if (infoX->usriX_flags) {
+ fields_present |= SAMR_FIELD_ACCT_FLAGS;
+ }
if (infoX->usriX_name) {
- fields_present |= SAMR_FIELD_FULL_NAME;
+ fields_present |= SAMR_FIELD_ACCOUNT_NAME;
}
if (infoX->usriX_password) {
fields_present |= SAMR_FIELD_PASSWORD;
@@ -64,8 +66,27 @@ static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X *infoX,
if (infoX->usriX_password_age) {
fields_present |= SAMR_FIELD_FORCE_PWD_CHANGE;
}
-
- acct_flags |= infoX->usriX_flags | ACB_NORMAL;
+ if (infoX->usriX_full_name) {
+ fields_present |= SAMR_FIELD_FULL_NAME;
+ }
+ if (infoX->usriX_usr_comment) {
+ fields_present |= SAMR_FIELD_COMMENT;
+ }
+ if (infoX->usriX_profile) {
+ fields_present |= SAMR_FIELD_PROFILE_PATH;
+ }
+ if (infoX->usriX_home_dir_drive) {
+ fields_present |= SAMR_FIELD_HOME_DRIVE;
+ }
+ if (infoX->usriX_primary_group_id) {
+ fields_present |= SAMR_FIELD_PRIMARY_GID;
+ }
+ if (infoX->usriX_country_code) {
+ fields_present |= SAMR_FIELD_COUNTRY_CODE;
+ }
+ if (infoX->usriX_workstations) {
+ fields_present |= SAMR_FIELD_WORKSTATIONS;
+ }
unix_to_nt_time_abs(&password_age, infoX->usriX_password_age);
@@ -77,24 +98,24 @@ static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X *infoX,
0,
0,
password_age,
- NULL,
infoX->usriX_name,
+ infoX->usriX_full_name,
infoX->usriX_home_dir,
- NULL,
+ infoX->usriX_home_dir_drive,
infoX->usriX_script_path,
- NULL,
+ infoX->usriX_profile,
infoX->usriX_comment,
- NULL,
- NULL,
+ infoX->usriX_workstations,
+ infoX->usriX_usr_comment,
&zero_parameters,
0,
- 0,
- acct_flags,
+ infoX->usriX_primary_group_id,
+ infoX->usriX_flags,
fields_present,
zero_logon_hours,
0,
0,
- 0,
+ infoX->usriX_country_code,
0,
0,
0,
@@ -111,7 +132,17 @@ static NTSTATUS construct_USER_INFO_X(uint32_t level,
struct USER_INFO_0 *u0 = NULL;
struct USER_INFO_1 *u1 = NULL;
struct USER_INFO_2 *u2 = NULL;
+ struct USER_INFO_1003 *u1003 = NULL;
+ struct USER_INFO_1006 *u1006 = NULL;
struct USER_INFO_1007 *u1007 = NULL;
+ struct USER_INFO_1009 *u1009 = NULL;
+ struct USER_INFO_1011 *u1011 = NULL;
+ struct USER_INFO_1012 *u1012 = NULL;
+ struct USER_INFO_1014 *u1014 = NULL;
+ struct USER_INFO_1024 *u1024 = NULL;
+ struct USER_INFO_1051 *u1051 = NULL;
+ struct USER_INFO_1052 *u1052 = NULL;
+ struct USER_INFO_1053 *u1053 = NULL;
if (!buffer || !uX) {
return NT_STATUS_INVALID_PARAMETER;
@@ -162,10 +193,50 @@ static NTSTATUS construct_USER_INFO_X(uint32_t level,
uX->usriX_country_code = u2->usri2_country_code;
uX->usriX_code_page = u2->usri2_code_page;
break;
+ case 1003:
+ u1003 = (struct USER_INFO_1003 *)buffer;
+ uX->usriX_password = u1003->usri1003_password;
+ break;
+ case 1006:
+ u1006 = (struct USER_INFO_1006 *)buffer;
+ uX->usriX_home_dir = u1006->usri1006_home_dir;
+ break;
case 1007:
u1007 = (struct USER_INFO_1007 *)buffer;
uX->usriX_comment = u1007->usri1007_comment;
break;
+ case 1009:
+ u1009 = (struct USER_INFO_1009 *)buffer;
+ uX->usriX_script_path = u1009->usri1009_script_path;
+ break;
+ case 1011:
+ u1011 = (struct USER_INFO_1011 *)buffer;
+ uX->usriX_full_name = u1011->usri1011_full_name;
+ break;
+ case 1012:
+ u1012 = (struct USER_INFO_1012 *)buffer;
+ uX->usriX_usr_comment = u1012->usri1012_usr_comment;
+ break;
+ case 1014:
+ u1014 = (struct USER_INFO_1014 *)buffer;
+ uX->usriX_workstations = u1014->usri1014_workstations;
+ break;
+ case 1024:
+ u1024 = (struct USER_INFO_1024 *)buffer;
+ uX->usriX_country_code = u1024->usri1024_country_code;
+ break;
+ case 1051:
+ u1051 = (struct USER_INFO_1051 *)buffer;
+ uX->usriX_primary_group_id = u1051->usri1051_primary_group_id;
+ break;
+ case 1052:
+ u1052 = (struct USER_INFO_1052 *)buffer;
+ uX->usriX_profile = u1052->usri1052_profile;
+ break;
+ case 1053:
+ u1053 = (struct USER_INFO_1053 *)buffer;
+ uX->usriX_home_dir_drive = u1053->usri1053_home_dir_drive;
+ break;
case 3:
case 4:
default:
@@ -178,6 +249,66 @@ static NTSTATUS construct_USER_INFO_X(uint32_t level,
/****************************************************************
****************************************************************/
+static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx,
+ struct rpc_pipe_client *pipe_cli,
+ DATA_BLOB *session_key,
+ struct policy_handle *user_handle,
+ struct USER_INFO_X *uX)
+{
+ union samr_UserInfo user_info;
+ struct samr_UserInfo21 info21;
+ NTSTATUS status;
+
+ if (!uX) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ convert_USER_INFO_X_to_samr_user_info21(uX, &info21);
+
+ ZERO_STRUCT(user_info);
+
+ if (uX->usriX_password) {
+
+ user_info.info25.info = info21;
+
+ init_samr_CryptPasswordEx(uX->usriX_password,
+ session_key,
+ &user_info.info25.password);
+
+ status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
+ user_handle,
+ 25,
+ &user_info);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
+
+ user_info.info23.info = info21;
+
+ init_samr_CryptPassword(uX->usriX_password,
+ session_key,
+ &user_info.info23.password);
+
+ status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
+ user_handle,
+ 23,
+ &user_info);
+ }
+ } else {
+
+ user_info.info21 = info21;
+
+ status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
+ user_handle,
+ 21,
+ &user_info);
+ }
+
+ return status;
+}
+
+/****************************************************************
+****************************************************************/
+
WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
struct NetUserAdd *r)
{
@@ -188,7 +319,6 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
POLICY_HND connect_handle, domain_handle, user_handle;
struct lsa_String lsa_account_name;
struct dom_sid2 *domain_sid = NULL;
- struct samr_UserInfo21 info21;
union samr_UserInfo *user_info = NULL;
struct samr_PwInfo pw_info;
uint32_t access_granted = 0;
@@ -282,47 +412,12 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
goto done;
}
- convert_USER_INFO_X_to_samr_user_info21(&uX,
- &info21);
-
- ZERO_STRUCTP(user_info);
-
- if (uX.usriX_password) {
-
- user_info->info25.info = info21;
-
- init_samr_CryptPasswordEx(uX.usriX_password,
- &cli->user_session_key,
- &user_info->info25.password);
-
- status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
- &user_handle,
- 25,
- user_info);
-
- if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
-
- user_info->info23.info = info21;
-
- init_samr_CryptPassword(uX.usriX_password,
- &cli->user_session_key,
- &user_info->info23.password);
-
- status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
- &user_handle,
- 23,
- user_info);
- }
- } else {
-
- user_info->info21 = info21;
+ uX.usriX_flags |= ACB_NORMAL;
- status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
- &user_handle,
- 21,
- user_info);
-
- }
+ status = set_user_info_USER_INFO_X(ctx, pipe_cli,
+ &cli->user_session_key,
+ &user_handle,
+ &uX);
if (!NT_STATUS_IS_OK(status)) {
werr = ntstatus_to_werror(status);
goto failed;
@@ -489,10 +584,12 @@ static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
struct policy_handle *domain_handle,
struct policy_handle *builtin_handle,
const char *user_name,
+ const struct dom_sid *domain_sid,
uint32_t rid,
uint32_t level,
struct samr_UserInfo21 **info21,
- struct sec_desc_buf **sec_desc)
+ struct sec_desc_buf **sec_desc,
+ uint32_t *auth_flag_p)
{
NTSTATUS status;
@@ -507,11 +604,20 @@ static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
switch (level) {
case 0:
+ break;
case 1:
+ access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
+ SAMR_USER_ACCESS_GET_GROUPS;
+ break;
case 2:
case 3:
- case 10:
+ case 4:
case 11:
+ access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
+ SAMR_USER_ACCESS_GET_GROUPS |
+ SAMR_USER_ACCESS_GET_LOCALE;
+ break;
+ case 10:
case 20:
case 23:
break;
@@ -548,7 +654,14 @@ static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
goto done;
}
- if (level == 1) {
+ if (access_mask & SAMR_USER_ACCESS_GET_GROUPS) {
+
+ struct lsa_SidArray sid_array;
+ struct samr_Ids alias_rids;
+ int i;
+ uint32_t auth_flag = 0;
+ struct dom_sid sid;
+
status = rpccli_samr_GetGroupsForUser(pipe_cli, mem_ctx,
&user_handle,
&rid_array);
@@ -556,15 +669,48 @@ static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
goto done;
}
-#if 0
- status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
- &builtin_handle,
- &sids,
- &rids);
+ sid_array.num_sids = rid_array->count + 1;
+ sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr,
+ sid_array.num_sids);
+ NT_STATUS_HAVE_NO_MEMORY(sid_array.sids);
+
+ for (i=0; i<rid_array->count; i++) {
+ sid_compose(&sid, domain_sid, rid_array->rids[i].rid);
+ sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
+ NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
+ }
+
+ sid_compose(&sid, domain_sid, rid);
+ sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid);
+ NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
+
+ status = rpccli_samr_GetAliasMembership(pipe_cli, mem_ctx,
+ builtin_handle,
+ &sid_array,
+ &alias_rids);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
-#endif
+
+ for (i=0; i<alias_rids.count; i++) {
+ switch (alias_rids.ids[i]) {
+ case 550: /* Print Operators */
+ auth_flag |= AF_OP_PRINT;
+ break;
+ case 549: /* Server Operators */
+ auth_flag |= AF_OP_SERVER;
+ break;
+ case 548: /* Account Operators */
+ auth_flag |= AF_OP_ACCOUNTS;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (auth_flag_p) {
+ *auth_flag_p = auth_flag;
+ }
}
*info21 = &user_info->info21;
@@ -580,6 +726,283 @@ static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
/****************************************************************
****************************************************************/
+static uint32_t samr_rid_to_priv_level(uint32_t rid)
+{
+ switch (rid) {
+ case DOMAIN_RID_ADMINISTRATOR:
+ return USER_PRIV_ADMIN;
+ case DOMAIN_RID_GUEST:
+ return USER_PRIV_GUEST;
+ default:
+ return USER_PRIV_USER;
+ }
+}
+
+/****************************************************************
+****************************************************************/
+
+static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
+{
+ uint32_t fl = UF_SCRIPT; /* god knows why */
+
+ fl |= ads_acb2uf(acb);
+
+ return fl;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS info21_to_USER_INFO_1(TALLOC_CTX *mem_ctx,
+ const struct samr_UserInfo21 *i21,
+ struct USER_INFO_1 *i)
+{
+ ZERO_STRUCTP(i);
+ i->usri1_name = talloc_strdup(mem_ctx, i21->account_name.string);
+ NT_STATUS_HAVE_NO_MEMORY(i->usri1_name);
+ i->usri1_password = NULL;
+ i->usri1_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
+ i->usri1_priv = samr_rid_to_priv_level(i21->rid);
+ i->usri1_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
+ i->usri1_comment = talloc_strdup(mem_ctx, i21->description.string);
+ i->usri1_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
+ i->usri1_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS info21_to_USER_INFO_2(TALLOC_CTX *mem_ctx,
+ const struct samr_UserInfo21 *i21,
+ uint32_t auth_flag,
+ struct USER_INFO_2 *i)
+{
+ ZERO_STRUCTP(i);
+
+ i->usri2_name = talloc_strdup(mem_ctx, i21->account_name.string);
+ NT_STATUS_HAVE_NO_MEMORY(i->usri2_name);
+ i->usri2_password = NULL;
+ i->usri2_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
+ i->usri2_priv = samr_rid_to_priv_level(i21->rid);
+ i->usri2_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
+ i->usri2_comment = talloc_strdup(mem_ctx, i21->description.string);
+ i->usri2_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
+ i->usri2_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
+ i->usri2_auth_flags = auth_flag;
+ i->usri2_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
+ i->usri2_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
+ i->usri2_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
+ i->usri2_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
+ i->usri2_last_logon = nt_time_to_unix(i21->last_logon);
+ i->usri2_last_logoff = nt_time_to_unix(i21->last_logoff);
+ i->usri2_acct_expires = nt_time_to_unix(i21->acct_expiry);
+ i->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
+ i->usri2_units_per_week = i21->logon_hours.units_per_week;
+ i->usri2_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
+ i->usri2_bad_pw_count = i21->bad_password_count;
+ i->usri2_num_logons = i21->logon_count;
+ i->usri2_logon_server = talloc_strdup(mem_ctx, "\\\\*");
+ i->usri2_country_code = i21->country_code;
+ i->usri2_code_page = i21->code_page;
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS info21_to_USER_INFO_3(TALLOC_CTX *mem_ctx,
+ const struct samr_UserInfo21 *i21,
+ uint32_t auth_flag,
+ struct USER_INFO_3 *i)
+{
+ ZERO_STRUCTP(i);
+
+ i->usri3_name = talloc_strdup(mem_ctx, i21->account_name.string);
+ NT_STATUS_HAVE_NO_MEMORY(i->usri3_name);
+ i->usri3_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
+ i->usri3_priv = samr_rid_to_priv_level(i21->rid);
+ i->usri3_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
+ i->usri3_comment = talloc_strdup(mem_ctx, i21->description.string);
+ i->usri3_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
+ i->usri3_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
+ i->usri3_auth_flags = auth_flag;
+ i->usri3_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
+ i->usri3_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
+ i->usri3_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
+ i->usri3_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
+ i->usri3_last_logon = nt_time_to_unix(i21->last_logon);
+ i->usri3_last_logoff = nt_time_to_unix(i21->last_logoff);
+ i->usri3_acct_expires = nt_time_to_unix(i21->acct_expiry);
+ i->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
+ i->usri3_units_per_week = i21->logon_hours.units_per_week;
+ i->usri3_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
+ i->usri3_bad_pw_count = i21->bad_password_count;
+ i->usri3_num_logons = i21->logon_count;
+ i->usri3_logon_server = talloc_strdup(mem_ctx, "\\\\*");
+ i->usri3_country_code = i21->country_code;
+ i->usri3_code_page = i21->code_page;
+ i->usri3_user_id = i21->rid;
+ i->usri3_primary_group_id = i21->primary_gid;
+ i->usri3_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
+ i->usri3_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
+ i->usri3_password_expired = i21->password_expired;
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS info21_to_USER_INFO_4(TALLOC_CTX *mem_ctx,
+ const struct samr_UserInfo21 *i21,
+ uint32_t auth_flag,
+ struct dom_sid *domain_sid,
+ struct USER_INFO_4 *i)
+{
+ struct dom_sid sid;
+
+ ZERO_STRUCTP(i);
+
+ i->usri4_name = talloc_strdup(mem_ctx, i21->account_name.string);
+ NT_STATUS_HAVE_NO_MEMORY(i->usri4_name);
+ i->usri4_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
+ i->usri4_password = NULL;
+ i->usri4_priv = samr_rid_to_priv_level(i21->rid);
+ i->usri4_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
+ i->usri4_comment = talloc_strdup(mem_ctx, i21->description.string);
+ i->usri4_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
+ i->usri4_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
+ i->usri4_auth_flags = auth_flag;
+ i->usri4_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
+ i->usri4_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
+ i->usri4_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
+ i->usri4_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
+ i->usri4_last_logon = nt_time_to_unix(i21->last_logon);
+ i->usri4_last_logoff = nt_time_to_unix(i21->last_logoff);
+ i->usri4_acct_expires = nt_time_to_unix(i21->acct_expiry);
+ i->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
+ i->usri4_units_per_week = i21->logon_hours.units_per_week;
+ i->usri4_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
+ i->usri4_bad_pw_count = i21->bad_password_count;
+ i->usri4_num_logons = i21->logon_count;
+ i->usri4_logon_server = talloc_strdup(mem_ctx, "\\\\*");
+ i->usri4_country_code = i21->country_code;
+ i->usri4_code_page = i21->code_page;
+ if (!sid_compose(&sid, domain_sid, i21->rid)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ i->usri4_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
+ i->usri4_primary_group_id = i21->primary_gid;
+ i->usri4_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
+ i->usri4_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
+ i->usri4_password_expired = i21->password_expired;
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS info21_to_USER_INFO_10(TALLOC_CTX *mem_ctx,
+ const struct samr_UserInfo21 *i21,
+ struct USER_INFO_10 *i)
+{
+ ZERO_STRUCTP(i);
+
+ i->usri10_name = talloc_strdup(mem_ctx, i21->account_name.string);
+ NT_STATUS_HAVE_NO_MEMORY(i->usri10_name);
+ i->usri10_comment = talloc_strdup(mem_ctx, i21->description.string);
+ i->usri10_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
+ i->usri10_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS info21_to_USER_INFO_11(TALLOC_CTX *mem_ctx,
+ const struct samr_UserInfo21 *i21,
+ uint32_t auth_flag,
+ struct USER_INFO_11 *i)
+{
+ ZERO_STRUCTP(i);
+
+ i->usri11_name = talloc_strdup(mem_ctx, i21->account_name.string);
+ NT_STATUS_HAVE_NO_MEMORY(i->usri11_name);
+ i->usri11_comment = talloc_strdup(mem_ctx, i21->description.string);
+ i->usri11_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
+ i->usri11_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
+ i->usri11_priv = samr_rid_to_priv_level(i21->rid);
+ i->usri11_auth_flags = auth_flag;
+ i->usri11_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
+ i->usri11_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
+ i->usri11_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
+ i->usri11_last_logon = nt_time_to_unix(i21->last_logon);
+ i->usri11_last_logoff = nt_time_to_unix(i21->last_logoff);
+ i->usri11_bad_pw_count = i21->bad_password_count;
+ i->usri11_num_logons = i21->logon_count;
+ i->usri11_logon_server = talloc_strdup(mem_ctx, "\\\\*");
+ i->usri11_country_code = i21->country_code;
+ i->usri11_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
+ i->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
+ i->usri11_units_per_week = i21->logon_hours.units_per_week;
+ i->usri11_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
+ i->usri11_code_page = i21->code_page;
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS info21_to_USER_INFO_20(TALLOC_CTX *mem_ctx,
+ const struct samr_UserInfo21 *i21,
+ struct USER_INFO_20 *i)
+{
+ ZERO_STRUCTP(i);
+
+ i->usri20_name = talloc_strdup(mem_ctx, i21->account_name.string);
+ NT_STATUS_HAVE_NO_MEMORY(i->usri20_name);
+ i->usri20_comment = talloc_strdup(mem_ctx, i21->description.string);
+ i->usri20_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
+ i->usri20_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
+ i->usri20_user_id = i21->rid;
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS info21_to_USER_INFO_23(TALLOC_CTX *mem_ctx,
+ const struct samr_UserInfo21 *i21,
+ struct dom_sid *domain_sid,
+ struct USER_INFO_23 *i)
+{
+ struct dom_sid sid;
+
+ ZERO_STRUCTP(i);
+
+ i->usri23_name = talloc_strdup(mem_ctx, i21->account_name.string);
+ NT_STATUS_HAVE_NO_MEMORY(i->usri23_name);
+ i->usri23_comment = talloc_strdup(mem_ctx, i21->description.string);
+ i->usri23_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
+ i->usri23_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
+ if (!sid_compose(&sid, domain_sid, i21->rid)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ i->usri23_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
struct rpc_pipe_client *pipe_cli,
struct dom_sid *domain_sid,
@@ -595,10 +1018,15 @@ static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
struct samr_UserInfo21 *info21 = NULL;
struct sec_desc_buf *sec_desc = NULL;
- struct dom_sid sid;
+ uint32_t auth_flag = 0;
struct USER_INFO_0 info0;
+ struct USER_INFO_1 info1;
+ struct USER_INFO_2 info2;
+ struct USER_INFO_3 info3;
+ struct USER_INFO_4 info4;
struct USER_INFO_10 info10;
+ struct USER_INFO_11 info11;
struct USER_INFO_20 info20;
struct USER_INFO_23 info23;
@@ -607,6 +1035,7 @@ static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
case 1:
case 2:
case 3:
+ case 4:
case 10:
case 11:
case 20:
@@ -630,73 +1059,86 @@ static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
domain_handle,
builtin_handle,
user_name,
+ domain_sid,
rid,
level,
&info21,
- &sec_desc);
+ &sec_desc,
+ &auth_flag);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
switch (level) {
- case 10:
- info10.usri10_name = talloc_strdup(mem_ctx, user_name);
- NT_STATUS_HAVE_NO_MEMORY(info10.usri10_name);
-
- info10.usri10_comment = talloc_strdup(mem_ctx,
- info21->description.string);
+ case 0:
+ /* already returned above */
+ break;
+ case 1:
+ status = info21_to_USER_INFO_1(mem_ctx, info21, &info1);
+ NT_STATUS_NOT_OK_RETURN(status);
- info10.usri10_full_name = talloc_strdup(mem_ctx,
- info21->full_name.string);
+ ADD_TO_ARRAY(mem_ctx, struct USER_INFO_1, info1,
+ (struct USER_INFO_1 **)buffer, num_entries);
- info10.usri10_usr_comment = talloc_strdup(mem_ctx,
- info21->comment.string);
+ break;
+ case 2:
+ status = info21_to_USER_INFO_2(mem_ctx, info21, auth_flag, &info2);
+ NT_STATUS_NOT_OK_RETURN(status);
- ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
- (struct USER_INFO_10 **)buffer, num_entries);
+ ADD_TO_ARRAY(mem_ctx, struct USER_INFO_2, info2,
+ (struct USER_INFO_2 **)buffer, num_entries);
break;
+ case 3:
+ status = info21_to_USER_INFO_3(mem_ctx, info21, auth_flag, &info3);
+ NT_STATUS_NOT_OK_RETURN(status);
- case 20:
- info20.usri20_name = talloc_strdup(mem_ctx, user_name);
- NT_STATUS_HAVE_NO_MEMORY(info20.usri20_name);
+ ADD_TO_ARRAY(mem_ctx, struct USER_INFO_3, info3,
+ (struct USER_INFO_3 **)buffer, num_entries);
- info20.usri20_comment = talloc_strdup(mem_ctx,
- info21->description.string);
+ break;
+ case 4:
+ status = info21_to_USER_INFO_4(mem_ctx, info21, auth_flag, domain_sid, &info4);
+ NT_STATUS_NOT_OK_RETURN(status);
- info20.usri20_full_name = talloc_strdup(mem_ctx,
- info21->full_name.string);
+ ADD_TO_ARRAY(mem_ctx, struct USER_INFO_4, info4,
+ (struct USER_INFO_4 **)buffer, num_entries);
- info20.usri20_flags = info21->acct_flags;
- info20.usri20_user_id = rid;
+ break;
+ case 10:
+ status = info21_to_USER_INFO_10(mem_ctx, info21, &info10);
+ NT_STATUS_NOT_OK_RETURN(status);
- ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
- (struct USER_INFO_20 **)buffer, num_entries);
+ ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
+ (struct USER_INFO_10 **)buffer, num_entries);
break;
- case 23:
- info23.usri23_name = talloc_strdup(mem_ctx, user_name);
- NT_STATUS_HAVE_NO_MEMORY(info23.usri23_name);
-
- info23.usri23_comment = talloc_strdup(mem_ctx,
- info21->description.string);
+ case 11:
+ status = info21_to_USER_INFO_11(mem_ctx, info21, auth_flag, &info11);
+ NT_STATUS_NOT_OK_RETURN(status);
- info23.usri23_full_name = talloc_strdup(mem_ctx,
- info21->full_name.string);
+ ADD_TO_ARRAY(mem_ctx, struct USER_INFO_11, info11,
+ (struct USER_INFO_11 **)buffer, num_entries);
- info23.usri23_flags = info21->acct_flags;
+ break;
+ case 20:
+ status = info21_to_USER_INFO_20(mem_ctx, info21, &info20);
+ NT_STATUS_NOT_OK_RETURN(status);
- if (!sid_compose(&sid, domain_sid, rid)) {
- return NT_STATUS_NO_MEMORY;
- }
+ ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
+ (struct USER_INFO_20 **)buffer, num_entries);
- info23.usri23_user_sid =
- (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
+ break;
+ case 23:
+ status = info21_to_USER_INFO_23(mem_ctx, info21, domain_sid, &info23);
+ NT_STATUS_NOT_OK_RETURN(status);
ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
(struct USER_INFO_23 **)buffer, num_entries);
break;
+ default:
+ return NT_STATUS_INVALID_LEVEL;
}
done:
@@ -713,7 +1155,7 @@ WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
struct rpc_pipe_client *pipe_cli = NULL;
struct policy_handle connect_handle;
struct dom_sid2 *domain_sid = NULL;
- struct policy_handle domain_handle;
+ struct policy_handle domain_handle, builtin_handle;
struct samr_SamArray *sam = NULL;
uint32_t filter = ACB_NORMAL;
int i;
@@ -724,6 +1166,7 @@ WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
ZERO_STRUCT(connect_handle);
ZERO_STRUCT(domain_handle);
+ ZERO_STRUCT(builtin_handle);
if (!r->out.buffer) {
return WERR_INVALID_PARAM;
@@ -734,16 +1177,17 @@ WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
switch (r->in.level) {
case 0:
- case 10:
- case 20:
- case 23:
- break;
case 1:
case 2:
case 3:
+ case 4:
+ case 10:
case 11:
+ case 20:
+ case 23:
+ break;
default:
- return WERR_NOT_SUPPORTED;
+ return WERR_UNKNOWN_LEVEL;
}
werr = libnetapi_open_pipe(ctx, r->in.server_name,
@@ -754,6 +1198,17 @@ WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
goto done;
}
+ werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
+ SAMR_ACCESS_ENUM_DOMAINS |
+ SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
+ SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
+ &connect_handle,
+ &builtin_handle);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
+ }
+
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_OPEN_DOMAIN,
@@ -805,7 +1260,7 @@ WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
domain_sid,
&domain_handle,
- NULL, /*&builtin_handle, */
+ &builtin_handle,
sam->entries[i].name.string,
sam->entries[i].idx,
r->in.level,
@@ -828,6 +1283,7 @@ WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
if (ctx->disable_policy_handle_cache) {
libnetapi_samr_close_domain_handle(ctx, &domain_handle);
+ libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
libnetapi_samr_close_connect_handle(ctx, &connect_handle);
}
}
@@ -1151,13 +1607,17 @@ WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
switch (r->in.level) {
case 0:
- /* case 1: */
+ case 1:
+ case 2:
+ case 3:
+ case 4:
case 10:
+ case 11:
case 20:
case 23:
break;
default:
- werr = WERR_NOT_SUPPORTED;
+ werr = WERR_UNKNOWN_LEVEL;
goto done;
}
@@ -1259,7 +1719,7 @@ WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
struct lsa_String lsa_account_name;
struct dom_sid2 *domain_sid = NULL;
struct samr_Ids user_rids, name_types;
- union samr_UserInfo user_info;
+ uint32_t user_mask = 0;
struct USER_INFO_X uX;
@@ -1274,11 +1734,41 @@ WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
switch (r->in.level) {
case 0:
+ case 1003:
+ user_mask = SAMR_USER_ACCESS_SET_PASSWORD;
+ break;
+ case 1006:
case 1007:
+ case 1009:
+ case 1011:
+ case 1014:
+ case 1052:
+ case 1053:
+ user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
break;
- default:
+ case 1012:
+ case 1024:
+ user_mask = SAMR_USER_ACCESS_SET_LOC_COM;
+ case 1051:
+ user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
+ SAMR_USER_ACCESS_GET_GROUPS;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 21:
+ case 22:
+ case 1005:
+ case 1008:
+ case 1010:
+ case 1017:
+ case 1020:
werr = WERR_NOT_SUPPORTED;
goto done;
+ default:
+ werr = WERR_UNKNOWN_LEVEL;
+ goto done;
}
werr = libnetapi_open_pipe(ctx, r->in.server_name,
@@ -1327,7 +1817,7 @@ WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
status = rpccli_samr_OpenUser(pipe_cli, ctx,
&domain_handle,
- SAMR_USER_ACCESS_SET_ATTRIBUTES,
+ user_mask,
user_rids.ids[0],
&user_handle);
if (!NT_STATUS_IS_OK(status)) {
@@ -1341,12 +1831,10 @@ WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
goto done;
}
- convert_USER_INFO_X_to_samr_user_info21(&uX, &user_info.info21);
-
- status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
- &user_handle,
- 21,
- &user_info);
+ status = set_user_info_USER_INFO_X(ctx, pipe_cli,
+ &cli->user_session_key,
+ &user_handle,
+ &uX);
if (!NT_STATUS_IS_OK(status)) {
werr = ntstatus_to_werror(status);
goto done;
@@ -2244,3 +2732,194 @@ WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
{
LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);
}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
+ uint32_t level,
+ const char *group_name,
+ uint32_t attributes,
+ uint8_t **buffer,
+ uint32_t *num_entries)
+{
+ struct GROUP_USERS_INFO_0 u0;
+ struct GROUP_USERS_INFO_1 u1;
+
+ switch (level) {
+ case 0:
+ u0.grui0_name = talloc_strdup(mem_ctx, group_name);
+ NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name);
+
+ ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0,
+ (struct GROUP_USERS_INFO_0 **)buffer, num_entries);
+ break;
+ case 1:
+ u1.grui1_name = talloc_strdup(mem_ctx, group_name);
+ NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name);
+
+ u1.grui1_attributes = attributes;
+
+ ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1,
+ (struct GROUP_USERS_INFO_1 **)buffer, num_entries);
+ break;
+ default:
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
+ struct NetUserGetGroups *r)
+{
+ struct cli_state *cli = NULL;
+ struct rpc_pipe_client *pipe_cli = NULL;
+ struct policy_handle connect_handle, domain_handle, user_handle;
+ struct lsa_String lsa_account_name;
+ struct dom_sid2 *domain_sid = NULL;
+ struct samr_Ids user_rids, name_types;
+ struct samr_RidWithAttributeArray *rid_array = NULL;
+ struct lsa_Strings names;
+ struct samr_Ids types;
+ uint32_t *rids = NULL;
+
+ int i;
+ uint32_t entries_read = 0;
+
+ NTSTATUS status = NT_STATUS_OK;
+ WERROR werr;
+
+ ZERO_STRUCT(connect_handle);
+ ZERO_STRUCT(domain_handle);
+
+ if (!r->out.buffer) {
+ return WERR_INVALID_PARAM;
+ }
+
+ *r->out.buffer = NULL;
+ *r->out.entries_read = 0;
+
+ switch (r->in.level) {
+ case 0:
+ case 1:
+ break;
+ default:
+ return WERR_UNKNOWN_LEVEL;
+ }
+
+ werr = libnetapi_open_pipe(ctx, r->in.server_name,
+ &ndr_table_samr.syntax_id,
+ &cli,
+ &pipe_cli);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
+ }
+
+ werr = libnetapi_samr_open_domain(ctx, pipe_cli,
+ SAMR_ACCESS_ENUM_DOMAINS |
+ SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+ &connect_handle,
+ &domain_handle,
+ &domain_sid);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
+ }
+
+ init_lsa_String(&lsa_account_name, r->in.user_name);
+
+ status = rpccli_samr_LookupNames(pipe_cli, ctx,
+ &domain_handle,
+ 1,
+ &lsa_account_name,
+ &user_rids,
+ &name_types);
+ if (!NT_STATUS_IS_OK(status)) {
+ werr = ntstatus_to_werror(status);
+ goto done;
+ }
+
+ status = rpccli_samr_OpenUser(pipe_cli, ctx,
+ &domain_handle,
+ SAMR_USER_ACCESS_GET_GROUPS,
+ user_rids.ids[0],
+ &user_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ werr = ntstatus_to_werror(status);
+ goto done;
+ }
+
+ status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
+ &user_handle,
+ &rid_array);
+ if (!NT_STATUS_IS_OK(status)) {
+ werr = ntstatus_to_werror(status);
+ goto done;
+ }
+
+ rids = talloc_array(ctx, uint32_t, rid_array->count);
+ if (!rids) {
+ werr = WERR_NOMEM;
+ goto done;
+ }
+
+ for (i=0; i < rid_array->count; i++) {
+ rids[i] = rid_array->rids[i].rid;
+ }
+
+ status = rpccli_samr_LookupRids(pipe_cli, ctx,
+ &domain_handle,
+ rid_array->count,
+ rids,
+ &names,
+ &types);
+ if (!NT_STATUS_IS_OK(status)) {
+ werr = ntstatus_to_werror(status);
+ goto done;
+ }
+
+ for (i=0; i < rid_array->count; i++) {
+ status = add_GROUP_USERS_INFO_X_buffer(ctx,
+ r->in.level,
+ names.names[i].string,
+ rid_array->rids[i].attributes,
+ r->out.buffer,
+ &entries_read);
+ if (!NT_STATUS_IS_OK(status)) {
+ werr = ntstatus_to_werror(status);
+ goto done;
+ }
+ }
+
+ if (r->out.entries_read) {
+ *r->out.entries_read = entries_read;
+ }
+ if (r->out.total_entries) {
+ *r->out.total_entries = entries_read;
+ }
+
+ done:
+ if (!cli) {
+ return werr;
+ }
+
+ if (ctx->disable_policy_handle_cache) {
+ libnetapi_samr_close_domain_handle(ctx, &domain_handle);
+ libnetapi_samr_close_connect_handle(ctx, &connect_handle);
+ }
+
+ return werr;
+}
+
+/****************************************************************
+****************************************************************/
+
+WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
+ struct NetUserGetGroups *r)
+{
+ LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups);
+}
diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c
index 77a50e4221..883f582445 100644
--- a/source3/libads/kerberos_keytab.c
+++ b/source3/libads/kerberos_keytab.c
@@ -161,15 +161,8 @@ int smb_krb5_kt_add_entry_ext(krb5_context context,
for (i = 0; enctypes[i]; i++) {
krb5_keyblock *keyp;
-#if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK)
-#error krb5_keytab_entry has no key or keyblock member
-#endif
-#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */
- keyp = &kt_entry.key;
-#endif
-#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */
- keyp = &kt_entry.keyblock;
-#endif
+ keyp = KRB5_KT_KEY(&kt_entry);
+
if (create_kerberos_key_from_string(context, princ, &password, keyp, enctypes[i], no_salt)) {
continue;
}
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index b7a15c558b..a39dee676f 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -1503,10 +1503,23 @@ static WERROR libnet_join_post_processing(TALLOC_CTX *mem_ctx,
return werr;
}
- if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
- saf_store(r->in.domain_name, r->in.dc_name);
+ if (!(r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE)) {
+ return WERR_OK;
}
+ saf_store(r->in.domain_name, r->in.dc_name);
+
+#ifdef WITH_ADS
+ if (r->out.domain_is_ad) {
+ ADS_STATUS ads_status;
+
+ ads_status = libnet_join_post_processing_ads(mem_ctx, r);
+ if (!ADS_ERR_OK(ads_status)) {
+ return WERR_GENERAL_FAILURE;
+ }
+ }
+#endif /* WITH_ADS */
+
libnet_join_add_dom_rids_to_builtins(r->out.domain_sid);
return WERR_OK;
@@ -1754,16 +1767,6 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
goto done;
}
-#ifdef WITH_ADS
- if (r->out.domain_is_ad) {
- ads_status = libnet_join_post_processing_ads(mem_ctx, r);
- if (!ADS_ERR_OK(ads_status)) {
- werr = WERR_GENERAL_FAILURE;
- goto done;
- }
- }
-#endif /* WITH_ADS */
-
werr = WERR_OK;
done:
diff --git a/source3/libnet/libnet_keytab.c b/source3/libnet/libnet_keytab.c
index 6447183958..46c17b219c 100644
--- a/source3/libnet/libnet_keytab.c
+++ b/source3/libnet/libnet_keytab.c
@@ -24,16 +24,6 @@
#ifdef HAVE_KRB5
-#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE /* Heimdal */
-#define KRB5_KEY_TYPE(k) ((k)->keytype)
-#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length)
-#define KRB5_KEY_DATA(k) ((k)->keyvalue.data)
-#else /* MIT */
-#define KRB5_KEY_TYPE(k) ((k)->enctype)
-#define KRB5_KEY_LENGTH(k) ((k)->length)
-#define KRB5_KEY_DATA(k) ((k)->contents)
-#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */
-
/****************************************************************
****************************************************************/
@@ -148,15 +138,7 @@ static krb5_error_code libnet_keytab_remove_entries(krb5_context context,
goto cont;
}
-#if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK)
-#error krb5_keytab_entry has no key or keyblock member
-#endif
-#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */
- keyp = &kt_entry.key;
-#endif
-#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */
- keyp = &kt_entry.keyblock;
-#endif
+ keyp = KRB5_KT_KEY(&kt_entry);
if (KRB5_KEY_TYPE(keyp) != enctype) {
goto cont;
@@ -250,15 +232,7 @@ static krb5_error_code libnet_keytab_add_entry(krb5_context context,
return ret;
}
-#if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK)
-#error krb5_keytab_entry has no key or keyblock member
-#endif
-#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */
- keyp = &kt_entry.key;
-#endif
-#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */
- keyp = &kt_entry.keyblock;
-#endif
+ keyp = KRB5_KT_KEY(&kt_entry);
if (create_kerberos_key_from_string(context, kt_entry.principal,
&password, keyp, enctype, true))
@@ -364,15 +338,7 @@ struct libnet_keytab_entry *libnet_keytab_search(struct libnet_keytab_context *c
goto cont;
}
-#if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK)
-#error krb5_keytab_entry has no key or keyblock member
-#endif
-#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */
- keyp = &kt_entry.key;
-#endif
-#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */
- keyp = &kt_entry.keyblock;
-#endif
+ keyp = KRB5_KT_KEY(&kt_entry);
if (KRB5_KEY_TYPE(keyp) != enctype) {
goto cont;
diff --git a/source3/librpc/gen_ndr/libnetapi.h b/source3/librpc/gen_ndr/libnetapi.h
index 825557d573..33ca253b60 100644
--- a/source3/librpc/gen_ndr/libnetapi.h
+++ b/source3/librpc/gen_ndr/libnetapi.h
@@ -10,7 +10,16 @@
#define _HEADER_libnetapi
#define ERROR_MORE_DATA ( 234L )
-#define ENCRYPTED_PWLEN ( 256 )
+#define USER_PRIV_GUEST ( 0 )
+#define USER_PRIV_USER ( 1 )
+#define USER_PRIV_ADMIN ( 2 )
+#define AF_OP_PRINT ( 0x1 )
+#define AF_OP_COMM ( 0x2 )
+#define AF_OP_SERVER ( 0x4 )
+#define AF_OP_ACCOUNTS ( 0x8 )
+#define AF_SETTABLE_BITS ( (AF_OP_PRINT|AF_OP_COMM|AF_OP_SERVER|AF_OP_ACCOUNTS) )
+#define USER_MAXSTORAGE_UNLIMITED ( (uint32_t)-1L )
+#define ENCRYPTED_PWLEN ( 16 )
#define FILTER_TEMP_DUPLICATE_ACCOUNT ( 0x0001 )
#define FILTER_NORMAL_ACCOUNT ( 0x0002 )
#define FILTER_INTERDOMAIN_TRUST_ACCOUNT ( 0x0008 )
@@ -35,6 +44,20 @@ struct domsid {
uint32_t *sub_auths;
};
+/* bitmap NetJoinFlags */
+#define NETSETUP_JOIN_DOMAIN ( 0x00000001 )
+#define NETSETUP_ACCT_CREATE ( 0x00000002 )
+#define NETSETUP_ACCT_DELETE ( 0x00000004 )
+#define NETSETUP_WIN9X_UPGRADE ( 0x00000010 )
+#define NETSETUP_DOMAIN_JOIN_IF_JOINED ( 0x00000020 )
+#define NETSETUP_JOIN_UNSECURE ( 0x00000040 )
+#define NETSETUP_MACHINE_PWD_PASSED ( 0x00000080 )
+#define NETSETUP_DEFER_SPN_SET ( 0x00000100 )
+#define NETSETUP_JOIN_DC_ACCOUNT ( 0x00000200 )
+#define NETSETUP_JOIN_WITH_NEW_NAME ( 0x00000400 )
+#define NETSETUP_INSTALL_INVOCATION ( 0x00040000 )
+#define NETSETUP_IGNORE_UNSUPPORTED_FLAGS ( 0x10000000 )
+
struct SERVER_INFO_1005 {
const char * sv1005_comment;
};
@@ -149,7 +172,7 @@ struct USER_INFO_4 {
const char * usri4_logon_server;
uint32_t usri4_country_code;
uint32_t usri4_code_page;
- struct dom_sid *usri4_user_sid;/* [unique] */
+ struct domsid *usri4_user_sid;/* [unique] */
uint32_t usri4_primary_group_id;
const char * usri4_profile;
const char * usri4_home_dir_drive;
@@ -339,6 +362,18 @@ struct USER_INFO_X {
const char * usriX_logon_server;
uint32_t usriX_country_code;
uint32_t usriX_code_page;
+ const char * usriX_profile;
+ const char * usriX_home_dir_drive;
+ uint32_t usriX_primary_group_id;
+};
+
+struct GROUP_USERS_INFO_0 {
+ const char * grui0_name;
+};
+
+struct GROUP_USERS_INFO_1 {
+ const char * grui1_name;
+ uint32_t grui1_attributes;
};
struct USER_MODALS_INFO_0 {
@@ -449,15 +484,6 @@ struct GROUP_INFO_1005 {
uint32_t grpi1005_attributes;
};
-struct GROUP_USERS_INFO_0 {
- const char * grui0_name;
-};
-
-struct GROUP_USERS_INFO_1 {
- const char * grui1_name;
- uint32_t grui1_attributes;
-};
-
struct LOCALGROUP_INFO_0 {
const char * lgrpi0_name;
};
@@ -535,6 +561,17 @@ struct TIME_OF_DAY_INFO {
uint32_t tod_weekday;
};
+struct SHARE_INFO_2 {
+ const char * shi2_netname;
+ uint32_t shi2_type;
+ const char * shi2_remark;
+ uint32_t shi2_permissions;
+ uint32_t shi2_max_uses;
+ uint32_t shi2_current_uses;
+ const char * shi2_path;
+ const char * shi2_passwd;
+};
+
struct NetJoinDomain {
struct {
@@ -767,6 +804,24 @@ struct NetUserSetInfo {
};
+struct NetUserGetGroups {
+ struct {
+ const char * server_name;
+ const char * user_name;
+ uint32_t level;
+ uint32_t prefmaxlen;
+ } in;
+
+ struct {
+ uint8_t **buffer;/* [ref] */
+ uint32_t *entries_read;/* [ref] */
+ uint32_t *total_entries;/* [ref] */
+ enum NET_API_STATUS result;
+ } out;
+
+};
+
+
struct NetUserModalsGet {
struct {
const char * server_name;
@@ -1098,4 +1153,19 @@ struct NetRemoteTOD {
};
+
+struct NetShareAdd {
+ struct {
+ const char * server_name;
+ uint32_t level;
+ uint8_t *buffer;/* [ref] */
+ } in;
+
+ struct {
+ uint32_t *parm_err;/* [ref] */
+ enum NET_API_STATUS result;
+ } out;
+
+};
+
#endif /* _HEADER_libnetapi */
diff --git a/source3/librpc/gen_ndr/ndr_libnetapi.c b/source3/librpc/gen_ndr/ndr_libnetapi.c
index 4d4a291a28..4f2579f256 100644
--- a/source3/librpc/gen_ndr/ndr_libnetapi.c
+++ b/source3/librpc/gen_ndr/ndr_libnetapi.c
@@ -87,6 +87,39 @@ _PUBLIC_ void ndr_print_domsid(struct ndr_print *ndr, const char *name, const st
ndr->depth--;
}
+_PUBLIC_ enum ndr_err_code ndr_push_NetJoinFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r)
+{
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_NetJoinFlags(struct ndr_pull *ndr, int ndr_flags, uint32_t *r)
+{
+ uint32_t v;
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
+ *r = v;
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_NetJoinFlags(struct ndr_print *ndr, const char *name, uint32_t r)
+{
+ ndr_print_uint32(ndr, name, r);
+ ndr->depth++;
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "NETSETUP_JOIN_DOMAIN", NETSETUP_JOIN_DOMAIN, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "NETSETUP_ACCT_CREATE", NETSETUP_ACCT_CREATE, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "NETSETUP_ACCT_DELETE", NETSETUP_ACCT_DELETE, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "NETSETUP_WIN9X_UPGRADE", NETSETUP_WIN9X_UPGRADE, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "NETSETUP_DOMAIN_JOIN_IF_JOINED", NETSETUP_DOMAIN_JOIN_IF_JOINED, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "NETSETUP_JOIN_UNSECURE", NETSETUP_JOIN_UNSECURE, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "NETSETUP_MACHINE_PWD_PASSED", NETSETUP_MACHINE_PWD_PASSED, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "NETSETUP_DEFER_SPN_SET", NETSETUP_DEFER_SPN_SET, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "NETSETUP_JOIN_DC_ACCOUNT", NETSETUP_JOIN_DC_ACCOUNT, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "NETSETUP_JOIN_WITH_NEW_NAME", NETSETUP_JOIN_WITH_NEW_NAME, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "NETSETUP_INSTALL_INVOCATION", NETSETUP_INSTALL_INVOCATION, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "NETSETUP_IGNORE_UNSUPPORTED_FLAGS", NETSETUP_IGNORE_UNSUPPORTED_FLAGS, r);
+ ndr->depth--;
+}
+
_PUBLIC_ enum ndr_err_code ndr_push_SERVER_INFO_1005(struct ndr_push *ndr, int ndr_flags, const struct SERVER_INFO_1005 *r)
{
if (ndr_flags & NDR_SCALARS) {
@@ -543,7 +576,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_USER_INFO_4(struct ndr_push *ndr, int ndr_fl
NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, *r->usri4_logon_hours));
}
if (r->usri4_user_sid) {
- NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS|NDR_BUFFERS, r->usri4_user_sid));
+ NDR_CHECK(ndr_push_domsid(ndr, NDR_SCALARS, r->usri4_user_sid));
}
}
return NDR_ERR_SUCCESS;
@@ -607,7 +640,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_USER_INFO_4(struct ndr_pull *ndr, int ndr_fl
if (r->usri4_user_sid) {
_mem_save_usri4_user_sid_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->usri4_user_sid, 0);
- NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS|NDR_BUFFERS, r->usri4_user_sid));
+ NDR_CHECK(ndr_pull_domsid(ndr, NDR_SCALARS, r->usri4_user_sid));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_usri4_user_sid_0, 0);
}
}
@@ -650,7 +683,7 @@ _PUBLIC_ void ndr_print_USER_INFO_4(struct ndr_print *ndr, const char *name, con
ndr_print_ptr(ndr, "usri4_user_sid", r->usri4_user_sid);
ndr->depth++;
if (r->usri4_user_sid) {
- ndr_print_dom_sid(ndr, "usri4_user_sid", r->usri4_user_sid);
+ ndr_print_domsid(ndr, "usri4_user_sid", r->usri4_user_sid);
}
ndr->depth--;
ndr_print_uint32(ndr, "usri4_primary_group_id", r->usri4_primary_group_id);
@@ -1716,6 +1749,9 @@ _PUBLIC_ enum ndr_err_code ndr_push_USER_INFO_X(struct ndr_push *ndr, int ndr_fl
NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->usriX_logon_server));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->usriX_country_code));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->usriX_code_page));
+ NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->usriX_profile));
+ NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->usriX_home_dir_drive));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->usriX_primary_group_id));
}
if (ndr_flags & NDR_BUFFERS) {
if (r->usriX_logon_hours) {
@@ -1760,6 +1796,9 @@ _PUBLIC_ enum ndr_err_code ndr_pull_USER_INFO_X(struct ndr_pull *ndr, int ndr_fl
NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->usriX_logon_server));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->usriX_country_code));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->usriX_code_page));
+ NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->usriX_profile));
+ NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->usriX_home_dir_drive));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->usriX_primary_group_id));
}
if (ndr_flags & NDR_BUFFERS) {
if (r->usriX_logon_hours) {
@@ -1805,6 +1844,72 @@ _PUBLIC_ void ndr_print_USER_INFO_X(struct ndr_print *ndr, const char *name, con
ndr_print_string(ndr, "usriX_logon_server", r->usriX_logon_server);
ndr_print_uint32(ndr, "usriX_country_code", r->usriX_country_code);
ndr_print_uint32(ndr, "usriX_code_page", r->usriX_code_page);
+ ndr_print_string(ndr, "usriX_profile", r->usriX_profile);
+ ndr_print_string(ndr, "usriX_home_dir_drive", r->usriX_home_dir_drive);
+ ndr_print_uint32(ndr, "usriX_primary_group_id", r->usriX_primary_group_id);
+ ndr->depth--;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_GROUP_USERS_INFO_0(struct ndr_push *ndr, int ndr_flags, const struct GROUP_USERS_INFO_0 *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->grui0_name));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_GROUP_USERS_INFO_0(struct ndr_pull *ndr, int ndr_flags, struct GROUP_USERS_INFO_0 *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->grui0_name));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_GROUP_USERS_INFO_0(struct ndr_print *ndr, const char *name, const struct GROUP_USERS_INFO_0 *r)
+{
+ ndr_print_struct(ndr, name, "GROUP_USERS_INFO_0");
+ ndr->depth++;
+ ndr_print_string(ndr, "grui0_name", r->grui0_name);
+ ndr->depth--;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_GROUP_USERS_INFO_1(struct ndr_push *ndr, int ndr_flags, const struct GROUP_USERS_INFO_1 *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->grui1_name));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->grui1_attributes));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_GROUP_USERS_INFO_1(struct ndr_pull *ndr, int ndr_flags, struct GROUP_USERS_INFO_1 *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->grui1_name));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->grui1_attributes));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_GROUP_USERS_INFO_1(struct ndr_print *ndr, const char *name, const struct GROUP_USERS_INFO_1 *r)
+{
+ ndr_print_struct(ndr, name, "GROUP_USERS_INFO_1");
+ ndr->depth++;
+ ndr_print_string(ndr, "grui1_name", r->grui1_name);
+ ndr_print_uint32(ndr, "grui1_attributes", r->grui1_attributes);
ndr->depth--;
}
@@ -1937,69 +2042,6 @@ _PUBLIC_ void ndr_print_NET_DISPLAY_GROUP(struct ndr_print *ndr, const char *nam
ndr->depth--;
}
-_PUBLIC_ enum ndr_err_code ndr_push_GROUP_USERS_INFO_0(struct ndr_push *ndr, int ndr_flags, const struct GROUP_USERS_INFO_0 *r)
-{
- if (ndr_flags & NDR_SCALARS) {
- NDR_CHECK(ndr_push_align(ndr, 4));
- NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->grui0_name));
- }
- if (ndr_flags & NDR_BUFFERS) {
- }
- return NDR_ERR_SUCCESS;
-}
-
-_PUBLIC_ enum ndr_err_code ndr_pull_GROUP_USERS_INFO_0(struct ndr_pull *ndr, int ndr_flags, struct GROUP_USERS_INFO_0 *r)
-{
- if (ndr_flags & NDR_SCALARS) {
- NDR_CHECK(ndr_pull_align(ndr, 4));
- NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->grui0_name));
- }
- if (ndr_flags & NDR_BUFFERS) {
- }
- return NDR_ERR_SUCCESS;
-}
-
-_PUBLIC_ void ndr_print_GROUP_USERS_INFO_0(struct ndr_print *ndr, const char *name, const struct GROUP_USERS_INFO_0 *r)
-{
- ndr_print_struct(ndr, name, "GROUP_USERS_INFO_0");
- ndr->depth++;
- ndr_print_string(ndr, "grui0_name", r->grui0_name);
- ndr->depth--;
-}
-
-_PUBLIC_ enum ndr_err_code ndr_push_GROUP_USERS_INFO_1(struct ndr_push *ndr, int ndr_flags, const struct GROUP_USERS_INFO_1 *r)
-{
- if (ndr_flags & NDR_SCALARS) {
- NDR_CHECK(ndr_push_align(ndr, 4));
- NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->grui1_name));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->grui1_attributes));
- }
- if (ndr_flags & NDR_BUFFERS) {
- }
- return NDR_ERR_SUCCESS;
-}
-
-_PUBLIC_ enum ndr_err_code ndr_pull_GROUP_USERS_INFO_1(struct ndr_pull *ndr, int ndr_flags, struct GROUP_USERS_INFO_1 *r)
-{
- if (ndr_flags & NDR_SCALARS) {
- NDR_CHECK(ndr_pull_align(ndr, 4));
- NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->grui1_name));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->grui1_attributes));
- }
- if (ndr_flags & NDR_BUFFERS) {
- }
- return NDR_ERR_SUCCESS;
-}
-
-_PUBLIC_ void ndr_print_GROUP_USERS_INFO_1(struct ndr_print *ndr, const char *name, const struct GROUP_USERS_INFO_1 *r)
-{
- ndr_print_struct(ndr, name, "GROUP_USERS_INFO_1");
- ndr->depth++;
- ndr_print_string(ndr, "grui1_name", r->grui1_name);
- ndr_print_uint32(ndr, "grui1_attributes", r->grui1_attributes);
- ndr->depth--;
-}
-
_PUBLIC_ void ndr_print_NetJoinDomain(struct ndr_print *ndr, const char *name, int flags, const struct NetJoinDomain *r)
{
ndr_print_struct(ndr, name, "NetJoinDomain");
@@ -2038,7 +2080,7 @@ _PUBLIC_ void ndr_print_NetJoinDomain(struct ndr_print *ndr, const char *name, i
ndr_print_string(ndr, "password", r->in.password);
}
ndr->depth--;
- ndr_print_uint32(ndr, "join_flags", r->in.join_flags);
+ ndr_print_NetJoinFlags(ndr, "join_flags", r->in.join_flags);
ndr->depth--;
}
if (flags & NDR_OUT) {
@@ -2078,7 +2120,7 @@ _PUBLIC_ void ndr_print_NetUnjoinDomain(struct ndr_print *ndr, const char *name,
ndr_print_string(ndr, "password", r->in.password);
}
ndr->depth--;
- ndr_print_uint32(ndr, "unjoin_flags", r->in.unjoin_flags);
+ ndr_print_NetJoinFlags(ndr, "unjoin_flags", r->in.unjoin_flags);
ndr->depth--;
}
if (flags & NDR_OUT) {
@@ -2613,6 +2655,48 @@ _PUBLIC_ void ndr_print_NetUserSetInfo(struct ndr_print *ndr, const char *name,
ndr->depth--;
}
+_PUBLIC_ void ndr_print_NetUserGetGroups(struct ndr_print *ndr, const char *name, int flags, const struct NetUserGetGroups *r)
+{
+ ndr_print_struct(ndr, name, "NetUserGetGroups");
+ ndr->depth++;
+ if (flags & NDR_SET_VALUES) {
+ ndr->flags |= LIBNDR_PRINT_SET_VALUES;
+ }
+ if (flags & NDR_IN) {
+ ndr_print_struct(ndr, "in", "NetUserGetGroups");
+ ndr->depth++;
+ ndr_print_string(ndr, "server_name", r->in.server_name);
+ ndr_print_string(ndr, "user_name", r->in.user_name);
+ ndr_print_uint32(ndr, "level", r->in.level);
+ ndr_print_uint32(ndr, "prefmaxlen", r->in.prefmaxlen);
+ ndr->depth--;
+ }
+ if (flags & NDR_OUT) {
+ ndr_print_struct(ndr, "out", "NetUserGetGroups");
+ ndr->depth++;
+ ndr_print_ptr(ndr, "buffer", r->out.buffer);
+ ndr->depth++;
+ ndr_print_ptr(ndr, "buffer", *r->out.buffer);
+ ndr->depth++;
+ if (*r->out.buffer) {
+ ndr_print_uint8(ndr, "buffer", **r->out.buffer);
+ }
+ ndr->depth--;
+ ndr->depth--;
+ ndr_print_ptr(ndr, "entries_read", r->out.entries_read);
+ ndr->depth++;
+ ndr_print_uint32(ndr, "entries_read", *r->out.entries_read);
+ ndr->depth--;
+ ndr_print_ptr(ndr, "total_entries", r->out.total_entries);
+ ndr->depth++;
+ ndr_print_uint32(ndr, "total_entries", *r->out.total_entries);
+ ndr->depth--;
+ ndr_print_NET_API_STATUS(ndr, "result", r->out.result);
+ ndr->depth--;
+ }
+ ndr->depth--;
+}
+
_PUBLIC_ void ndr_print_NetUserModalsGet(struct ndr_print *ndr, const char *name, int flags, const struct NetUserModalsGet *r)
{
ndr_print_struct(ndr, name, "NetUserModalsGet");
@@ -3313,3 +3397,34 @@ _PUBLIC_ void ndr_print_NetRemoteTOD(struct ndr_print *ndr, const char *name, in
ndr->depth--;
}
+_PUBLIC_ void ndr_print_NetShareAdd(struct ndr_print *ndr, const char *name, int flags, const struct NetShareAdd *r)
+{
+ ndr_print_struct(ndr, name, "NetShareAdd");
+ ndr->depth++;
+ if (flags & NDR_SET_VALUES) {
+ ndr->flags |= LIBNDR_PRINT_SET_VALUES;
+ }
+ if (flags & NDR_IN) {
+ ndr_print_struct(ndr, "in", "NetShareAdd");
+ ndr->depth++;
+ ndr_print_string(ndr, "server_name", r->in.server_name);
+ ndr_print_uint32(ndr, "level", r->in.level);
+ ndr_print_ptr(ndr, "buffer", r->in.buffer);
+ ndr->depth++;
+ ndr_print_uint8(ndr, "buffer", *r->in.buffer);
+ ndr->depth--;
+ ndr->depth--;
+ }
+ if (flags & NDR_OUT) {
+ ndr_print_struct(ndr, "out", "NetShareAdd");
+ ndr->depth++;
+ ndr_print_ptr(ndr, "parm_err", r->out.parm_err);
+ ndr->depth++;
+ ndr_print_uint32(ndr, "parm_err", *r->out.parm_err);
+ ndr->depth--;
+ ndr_print_NET_API_STATUS(ndr, "result", r->out.result);
+ ndr->depth--;
+ }
+ ndr->depth--;
+}
+
diff --git a/source3/librpc/gen_ndr/ndr_libnetapi.h b/source3/librpc/gen_ndr/ndr_libnetapi.h
index 9b5d8e7c35..8324ac3188 100644
--- a/source3/librpc/gen_ndr/ndr_libnetapi.h
+++ b/source3/librpc/gen_ndr/ndr_libnetapi.h
@@ -36,55 +36,62 @@
#define NDR_NETUSERSETINFO (0x0e)
-#define NDR_NETUSERMODALSGET (0x0f)
+#define NDR_NETUSERGETGROUPS (0x0f)
-#define NDR_NETUSERMODALSSET (0x10)
+#define NDR_NETUSERMODALSGET (0x10)
-#define NDR_NETQUERYDISPLAYINFORMATION (0x11)
+#define NDR_NETUSERMODALSSET (0x11)
-#define NDR_NETGROUPADD (0x12)
+#define NDR_NETQUERYDISPLAYINFORMATION (0x12)
-#define NDR_NETGROUPDEL (0x13)
+#define NDR_NETGROUPADD (0x13)
-#define NDR_NETGROUPENUM (0x14)
+#define NDR_NETGROUPDEL (0x14)
-#define NDR_NETGROUPSETINFO (0x15)
+#define NDR_NETGROUPENUM (0x15)
-#define NDR_NETGROUPGETINFO (0x16)
+#define NDR_NETGROUPSETINFO (0x16)
-#define NDR_NETGROUPADDUSER (0x17)
+#define NDR_NETGROUPGETINFO (0x17)
-#define NDR_NETGROUPDELUSER (0x18)
+#define NDR_NETGROUPADDUSER (0x18)
-#define NDR_NETGROUPGETUSERS (0x19)
+#define NDR_NETGROUPDELUSER (0x19)
-#define NDR_NETLOCALGROUPADD (0x1a)
+#define NDR_NETGROUPGETUSERS (0x1a)
-#define NDR_NETLOCALGROUPDEL (0x1b)
+#define NDR_NETLOCALGROUPADD (0x1b)
-#define NDR_NETLOCALGROUPGETINFO (0x1c)
+#define NDR_NETLOCALGROUPDEL (0x1c)
-#define NDR_NETLOCALGROUPSETINFO (0x1d)
+#define NDR_NETLOCALGROUPGETINFO (0x1d)
-#define NDR_NETLOCALGROUPENUM (0x1e)
+#define NDR_NETLOCALGROUPSETINFO (0x1e)
-#define NDR_NETLOCALGROUPADDMEMBERS (0x1f)
+#define NDR_NETLOCALGROUPENUM (0x1f)
-#define NDR_NETLOCALGROUPDELMEMBERS (0x20)
+#define NDR_NETLOCALGROUPADDMEMBERS (0x20)
-#define NDR_NETLOCALGROUPGETMEMBERS (0x21)
+#define NDR_NETLOCALGROUPDELMEMBERS (0x21)
-#define NDR_NETLOCALGROUPSETMEMBERS (0x22)
+#define NDR_NETLOCALGROUPGETMEMBERS (0x22)
-#define NDR_NETREMOTETOD (0x23)
+#define NDR_NETLOCALGROUPSETMEMBERS (0x23)
-#define NDR_LIBNETAPI_CALL_COUNT (36)
+#define NDR_NETREMOTETOD (0x24)
+
+#define NDR_NETSHAREADD (0x25)
+
+#define NDR_LIBNETAPI_CALL_COUNT (38)
enum ndr_err_code ndr_push_NET_API_STATUS(struct ndr_push *ndr, int ndr_flags, enum NET_API_STATUS r);
enum ndr_err_code ndr_pull_NET_API_STATUS(struct ndr_pull *ndr, int ndr_flags, enum NET_API_STATUS *r);
void ndr_print_NET_API_STATUS(struct ndr_print *ndr, const char *name, enum NET_API_STATUS r);
enum ndr_err_code ndr_push_domsid(struct ndr_push *ndr, int ndr_flags, const struct domsid *r);
enum ndr_err_code ndr_pull_domsid(struct ndr_pull *ndr, int ndr_flags, struct domsid *r);
void ndr_print_domsid(struct ndr_print *ndr, const char *name, const struct domsid *r);
+enum ndr_err_code ndr_push_NetJoinFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r);
+enum ndr_err_code ndr_pull_NetJoinFlags(struct ndr_pull *ndr, int ndr_flags, uint32_t *r);
+void ndr_print_NetJoinFlags(struct ndr_print *ndr, const char *name, uint32_t r);
enum ndr_err_code ndr_push_SERVER_INFO_1005(struct ndr_push *ndr, int ndr_flags, const struct SERVER_INFO_1005 *r);
enum ndr_err_code ndr_pull_SERVER_INFO_1005(struct ndr_pull *ndr, int ndr_flags, struct SERVER_INFO_1005 *r);
void ndr_print_SERVER_INFO_1005(struct ndr_print *ndr, const char *name, const struct SERVER_INFO_1005 *r);
@@ -187,6 +194,12 @@ void ndr_print_USER_INFO_1053(struct ndr_print *ndr, const char *name, const str
enum ndr_err_code ndr_push_USER_INFO_X(struct ndr_push *ndr, int ndr_flags, const struct USER_INFO_X *r);
enum ndr_err_code ndr_pull_USER_INFO_X(struct ndr_pull *ndr, int ndr_flags, struct USER_INFO_X *r);
void ndr_print_USER_INFO_X(struct ndr_print *ndr, const char *name, const struct USER_INFO_X *r);
+enum ndr_err_code ndr_push_GROUP_USERS_INFO_0(struct ndr_push *ndr, int ndr_flags, const struct GROUP_USERS_INFO_0 *r);
+enum ndr_err_code ndr_pull_GROUP_USERS_INFO_0(struct ndr_pull *ndr, int ndr_flags, struct GROUP_USERS_INFO_0 *r);
+void ndr_print_GROUP_USERS_INFO_0(struct ndr_print *ndr, const char *name, const struct GROUP_USERS_INFO_0 *r);
+enum ndr_err_code ndr_push_GROUP_USERS_INFO_1(struct ndr_push *ndr, int ndr_flags, const struct GROUP_USERS_INFO_1 *r);
+enum ndr_err_code ndr_pull_GROUP_USERS_INFO_1(struct ndr_pull *ndr, int ndr_flags, struct GROUP_USERS_INFO_1 *r);
+void ndr_print_GROUP_USERS_INFO_1(struct ndr_print *ndr, const char *name, const struct GROUP_USERS_INFO_1 *r);
enum ndr_err_code ndr_push_NET_DISPLAY_USER(struct ndr_push *ndr, int ndr_flags, const struct NET_DISPLAY_USER *r);
enum ndr_err_code ndr_pull_NET_DISPLAY_USER(struct ndr_pull *ndr, int ndr_flags, struct NET_DISPLAY_USER *r);
void ndr_print_NET_DISPLAY_USER(struct ndr_print *ndr, const char *name, const struct NET_DISPLAY_USER *r);
@@ -196,12 +209,6 @@ void ndr_print_NET_DISPLAY_MACHINE(struct ndr_print *ndr, const char *name, cons
enum ndr_err_code ndr_push_NET_DISPLAY_GROUP(struct ndr_push *ndr, int ndr_flags, const struct NET_DISPLAY_GROUP *r);
enum ndr_err_code ndr_pull_NET_DISPLAY_GROUP(struct ndr_pull *ndr, int ndr_flags, struct NET_DISPLAY_GROUP *r);
void ndr_print_NET_DISPLAY_GROUP(struct ndr_print *ndr, const char *name, const struct NET_DISPLAY_GROUP *r);
-enum ndr_err_code ndr_push_GROUP_USERS_INFO_0(struct ndr_push *ndr, int ndr_flags, const struct GROUP_USERS_INFO_0 *r);
-enum ndr_err_code ndr_pull_GROUP_USERS_INFO_0(struct ndr_pull *ndr, int ndr_flags, struct GROUP_USERS_INFO_0 *r);
-void ndr_print_GROUP_USERS_INFO_0(struct ndr_print *ndr, const char *name, const struct GROUP_USERS_INFO_0 *r);
-enum ndr_err_code ndr_push_GROUP_USERS_INFO_1(struct ndr_push *ndr, int ndr_flags, const struct GROUP_USERS_INFO_1 *r);
-enum ndr_err_code ndr_pull_GROUP_USERS_INFO_1(struct ndr_pull *ndr, int ndr_flags, struct GROUP_USERS_INFO_1 *r);
-void ndr_print_GROUP_USERS_INFO_1(struct ndr_print *ndr, const char *name, const struct GROUP_USERS_INFO_1 *r);
enum ndr_err_code ndr_push_NetJoinDomain(struct ndr_push *ndr, int flags, const struct NetJoinDomain *r);
enum ndr_err_code ndr_pull_NetJoinDomain(struct ndr_pull *ndr, int flags, struct NetJoinDomain *r);
void ndr_print_NetJoinDomain(struct ndr_print *ndr, const char *name, int flags, const struct NetJoinDomain *r);
@@ -247,6 +254,9 @@ void ndr_print_NetUserGetInfo(struct ndr_print *ndr, const char *name, int flags
enum ndr_err_code ndr_push_NetUserSetInfo(struct ndr_push *ndr, int flags, const struct NetUserSetInfo *r);
enum ndr_err_code ndr_pull_NetUserSetInfo(struct ndr_pull *ndr, int flags, struct NetUserSetInfo *r);
void ndr_print_NetUserSetInfo(struct ndr_print *ndr, const char *name, int flags, const struct NetUserSetInfo *r);
+enum ndr_err_code ndr_push_NetUserGetGroups(struct ndr_push *ndr, int flags, const struct NetUserGetGroups *r);
+enum ndr_err_code ndr_pull_NetUserGetGroups(struct ndr_pull *ndr, int flags, struct NetUserGetGroups *r);
+void ndr_print_NetUserGetGroups(struct ndr_print *ndr, const char *name, int flags, const struct NetUserGetGroups *r);
enum ndr_err_code ndr_push_NetUserModalsGet(struct ndr_push *ndr, int flags, const struct NetUserModalsGet *r);
enum ndr_err_code ndr_pull_NetUserModalsGet(struct ndr_pull *ndr, int flags, struct NetUserModalsGet *r);
void ndr_print_NetUserModalsGet(struct ndr_print *ndr, const char *name, int flags, const struct NetUserModalsGet *r);
@@ -310,4 +320,7 @@ void ndr_print_NetLocalGroupSetMembers(struct ndr_print *ndr, const char *name,
enum ndr_err_code ndr_push_NetRemoteTOD(struct ndr_push *ndr, int flags, const struct NetRemoteTOD *r);
enum ndr_err_code ndr_pull_NetRemoteTOD(struct ndr_pull *ndr, int flags, struct NetRemoteTOD *r);
void ndr_print_NetRemoteTOD(struct ndr_print *ndr, const char *name, int flags, const struct NetRemoteTOD *r);
+enum ndr_err_code ndr_push_NetShareAdd(struct ndr_push *ndr, int flags, const struct NetShareAdd *r);
+enum ndr_err_code ndr_pull_NetShareAdd(struct ndr_pull *ndr, int flags, struct NetShareAdd *r);
+void ndr_print_NetShareAdd(struct ndr_print *ndr, const char *name, int flags, const struct NetShareAdd *r);
#endif /* _HEADER_NDR_libnetapi */
diff --git a/source3/librpc/idl/libnetapi.idl b/source3/librpc/idl/libnetapi.idl
index 1bb0aafe94..0b91876832 100644
--- a/source3/librpc/idl/libnetapi.idl
+++ b/source3/librpc/idl/libnetapi.idl
@@ -29,13 +29,28 @@ interface libnetapi
/* NetJoinDomain */
/*******************************************/
+ typedef [public,bitmap32bit] bitmap {
+ NETSETUP_JOIN_DOMAIN = 0x00000001,
+ NETSETUP_ACCT_CREATE = 0x00000002,
+ NETSETUP_ACCT_DELETE = 0x00000004,
+ NETSETUP_WIN9X_UPGRADE = 0x00000010,
+ NETSETUP_DOMAIN_JOIN_IF_JOINED = 0x00000020,
+ NETSETUP_JOIN_UNSECURE = 0x00000040,
+ NETSETUP_MACHINE_PWD_PASSED = 0x00000080,
+ NETSETUP_DEFER_SPN_SET = 0x00000100,
+ NETSETUP_JOIN_DC_ACCOUNT = 0x00000200,
+ NETSETUP_JOIN_WITH_NEW_NAME = 0x00000400,
+ NETSETUP_INSTALL_INVOCATION = 0x00040000,
+ NETSETUP_IGNORE_UNSUPPORTED_FLAGS = 0x10000000
+ } NetJoinFlags;
+
[nopush,nopull] NET_API_STATUS NetJoinDomain(
[in,unique] string *server,
[in,ref] string *domain,
[in,unique] string *account_ou,
[in,unique] string *account,
[in,unique] string *password,
- [in] uint32 join_flags
+ [in] NetJoinFlags join_flags
);
/*******************************************/
@@ -46,7 +61,7 @@ interface libnetapi
[in,unique] string *server_name,
[in,unique] string *account,
[in,unique] string *password,
- [in] uint32 unjoin_flags
+ [in] NetJoinFlags unjoin_flags
);
/*******************************************/
@@ -150,6 +165,11 @@ interface libnetapi
string usri0_name;
} USER_INFO_0;
+ /* priv */
+ const int USER_PRIV_GUEST = 0;
+ const int USER_PRIV_USER = 1;
+ const int USER_PRIV_ADMIN = 2;
+
[public] typedef struct {
string usri1_name;
string usri1_password;
@@ -161,6 +181,16 @@ interface libnetapi
string usri1_script_path;
} USER_INFO_1;
+ /* auth_flags in USER_INFO_2 */
+
+ const int AF_OP_PRINT = 0x1;
+ const int AF_OP_COMM = 0x2;
+ const int AF_OP_SERVER = 0x4;
+ const int AF_OP_ACCOUNTS = 0x8;
+ const int AF_SETTABLE_BITS = (AF_OP_PRINT | AF_OP_COMM | AF_OP_SERVER | AF_OP_ACCOUNTS);
+
+ const int USER_MAXSTORAGE_UNLIMITED = (uint32_t)-1L;
+
[public] typedef struct {
string usri2_name;
string usri2_password;
@@ -244,7 +274,7 @@ interface libnetapi
string usri4_logon_server;
uint32 usri4_country_code;
uint32 usri4_code_page;
- dom_sid *usri4_user_sid;
+ domsid *usri4_user_sid;
uint32 usri4_primary_group_id;
string usri4_profile;
string usri4_home_dir_drive;
@@ -289,7 +319,7 @@ interface libnetapi
uint32 usri20_user_id;
} USER_INFO_20;
- const int ENCRYPTED_PWLEN = 256;
+ const int ENCRYPTED_PWLEN = 16;
[public] typedef struct {
uint8 usri21_password[ENCRYPTED_PWLEN];
@@ -436,6 +466,9 @@ interface libnetapi
string usriX_logon_server;
uint32 usriX_country_code;
uint32 usriX_code_page;
+ string usriX_profile;
+ string usriX_home_dir_drive;
+ uint32 usriX_primary_group_id;
} USER_INFO_X;
[nopush,nopull] NET_API_STATUS NetUserAdd(
@@ -510,6 +543,29 @@ interface libnetapi
);
/*******************************************/
+ /* NetUserGetGroups */
+ /*******************************************/
+
+ [public] typedef struct {
+ string grui0_name;
+ } GROUP_USERS_INFO_0;
+
+ [public] typedef struct {
+ string grui1_name;
+ uint32 grui1_attributes;
+ } GROUP_USERS_INFO_1;
+
+ [nopush,nopull] NET_API_STATUS NetUserGetGroups(
+ [in] string server_name,
+ [in] string user_name,
+ [in] uint32 level,
+ [out] uint8 **buffer,
+ [in] uint32 prefmaxlen,
+ [out,ref] uint32 *entries_read,
+ [out,ref] uint32 *total_entries
+ );
+
+ /*******************************************/
/* NetUserModalsGet */
/*******************************************/
@@ -735,15 +791,6 @@ interface libnetapi
/* NetGroupGetUsers */
/*******************************************/
- [public] typedef struct {
- string grui0_name;
- } GROUP_USERS_INFO_0;
-
- [public] typedef struct {
- string grui1_name;
- uint32 grui1_attributes;
- } GROUP_USERS_INFO_1;
-
[nopush,nopull] NET_API_STATUS NetGroupGetUsers(
[in] string server_name,
[in] string group_name,
@@ -932,4 +979,26 @@ interface libnetapi
[in] string server_name,
[out,ref] uint8 **buffer
);
+
+ /*******************************************/
+ /* NetShareAdd */
+ /*******************************************/
+
+ typedef struct {
+ string shi2_netname;
+ uint32 shi2_type;
+ string shi2_remark;
+ uint32 shi2_permissions;
+ uint32 shi2_max_uses;
+ uint32 shi2_current_uses;
+ string shi2_path;
+ string shi2_passwd;
+ } SHARE_INFO_2;
+
+ [nopush,nopull] NET_API_STATUS NetShareAdd(
+ [in] string server_name,
+ [in] uint32 level,
+ [in] uint8 *buffer,
+ [out] uint32 *parm_err
+ );
}
diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c
index fa21ad3467..bedd7d7aee 100644
--- a/source3/libsmb/clikrb5.c
+++ b/source3/libsmb/clikrb5.c
@@ -27,18 +27,6 @@
#ifdef HAVE_KRB5
-#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE /* Heimdal */
-#define KRB5_KEY_TYPE(k) ((k)->keytype)
-#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length)
-#define KRB5_KEY_DATA(k) ((k)->keyvalue.data)
-#define KRB5_KEY_DATA_CAST void
-#else /* MIT */
-#define KRB5_KEY_TYPE(k) ((k)->enctype)
-#define KRB5_KEY_LENGTH(k) ((k)->length)
-#define KRB5_KEY_DATA(k) ((k)->contents)
-#define KRB5_KEY_DATA_CAST krb5_octet
-#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */
-
#define GSSAPI_CHECKSUM 0x8003 /* Checksum type value for Kerberos */
#define GSSAPI_BNDLENGTH 16 /* Bind Length (rfc-1964 pg.3) */
#define GSSAPI_CHECKSUM_SIZE (12+GSSAPI_BNDLENGTH)
@@ -1057,6 +1045,7 @@ get_key_from_keytab(krb5_context context,
krb5_error_code ret;
krb5_keytab keytab;
char *name = NULL;
+ krb5_keyblock *keyp;
/* We have to open a new keytab handle here, as MIT does
an implicit open/getnext/close on krb5_kt_get_entry. We
@@ -1089,14 +1078,9 @@ get_key_from_keytab(krb5_context context,
goto out;
}
-#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */
- ret = krb5_copy_keyblock(context, &entry.keyblock, out_key);
-#elif defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) /* MIT */
- ret = krb5_copy_keyblock(context, &entry.key, out_key);
-#else
-#error UNKNOWN_KRB5_KEYTAB_ENTRY_FORMAT
-#endif
+ keyp = KRB5_KT_KEY(&entry);
+ ret = krb5_copy_keyblock(context, keyp, out_key);
if (ret) {
DEBUG(0,("get_key_from_keytab: failed to copy key: %s\n", error_message(ret)));
goto out;
@@ -1584,15 +1568,9 @@ done:
#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_FREE */
}
- krb5_enctype smb_get_enctype_from_kt_entry(const krb5_keytab_entry *kt_entry)
+ krb5_enctype smb_get_enctype_from_kt_entry(krb5_keytab_entry *kt_entry)
{
-#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */
- return kt_entry->key.enctype;
-#elif defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK) /* Heimdal */
- return kt_entry->keyblock.keytype;
-#else
-#error UNKNOWN_KRB5_KEYTAB_ENTRY_KEYBLOCK_FORMAT
-#endif
+ return KRB5_KEY_TYPE(KRB5_KT_KEY(kt_entry));
}
diff --git a/source3/nsswitch/libwbclient/wbc_pam.c b/source3/nsswitch/libwbclient/wbc_pam.c
index 293f71c347..20b42b6efb 100644
--- a/source3/nsswitch/libwbclient/wbc_pam.c
+++ b/source3/nsswitch/libwbclient/wbc_pam.c
@@ -236,6 +236,30 @@ done:
return wbc_status;
}
+static wbcErr wbc_create_password_policy_info(TALLOC_CTX *mem_ctx,
+ const struct winbindd_response *resp,
+ struct wbcUserPasswordPolicyInfo **_i)
+{
+ wbcErr wbc_status = WBC_ERR_SUCCESS;
+ struct wbcUserPasswordPolicyInfo *i;
+
+ i = talloc(mem_ctx, struct wbcUserPasswordPolicyInfo);
+ BAIL_ON_PTR_ERROR(i, wbc_status);
+
+ i->min_passwordage = resp->data.auth.policy.min_passwordage;
+ i->min_length_password = resp->data.auth.policy.min_length_password;
+ i->password_history = resp->data.auth.policy.password_history;
+ i->password_properties = resp->data.auth.policy.password_properties;
+ i->expire = resp->data.auth.policy.expire;
+
+ *_i = i;
+ i = NULL;
+
+done:
+ talloc_free(i);
+ return wbc_status;
+}
+
/** @brief Authenticate with more detailed information
*
* @param params Input parameters, WBC_AUTH_USER_LEVEL_HASH
@@ -523,3 +547,250 @@ wbcErr wbcLogoffUser(const char *username,
done:
return wbc_status;
}
+
+/** @brief Change a password for a user with more detailed information upon
+ * failure
+ * @param params Input parameters
+ * @param error User output details on WBC_ERR_PWD_CHANGE_FAILED
+ * @param reject_reason New password reject reason on WBC_ERR_PWD_CHANGE_FAILED
+ * @param policy Password policy output details on WBC_ERR_PWD_CHANGE_FAILED
+ *
+ * @return #wbcErr
+ **/
+
+wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
+ struct wbcAuthErrorInfo **error,
+ enum wbcPasswordChangeRejectReason *reject_reason,
+ struct wbcUserPasswordPolicyInfo **policy)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ int cmd = 0;
+
+ /* validate input */
+
+ if (!params->account_name) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (error) {
+ *error = NULL;
+ }
+
+ if (policy) {
+ *policy = NULL;
+ }
+
+ if (reject_reason) {
+ *reject_reason = -1;
+ }
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ switch (params->level) {
+ case WBC_CHANGE_PASSWORD_LEVEL_PLAIN:
+ cmd = WINBINDD_PAM_CHAUTHTOK;
+
+ if (!params->account_name) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ strncpy(request.data.chauthtok.user, params->account_name,
+ sizeof(request.data.chauthtok.user) - 1);
+
+ if (params->old_password.plaintext) {
+ strncpy(request.data.chauthtok.oldpass,
+ params->old_password.plaintext,
+ sizeof(request.data.chauthtok.oldpass) - 1);
+ }
+
+ if (params->new_password.plaintext) {
+ strncpy(request.data.chauthtok.newpass,
+ params->new_password.plaintext,
+ sizeof(request.data.chauthtok.newpass) - 1);
+ }
+ break;
+
+ case WBC_CHANGE_PASSWORD_LEVEL_RESPONSE:
+ cmd = WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP;
+
+ if (!params->account_name || !params->domain_name) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (params->old_password.response.old_lm_hash_enc_length &&
+ !params->old_password.response.old_lm_hash_enc_data) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (params->old_password.response.old_lm_hash_enc_length == 0 &&
+ params->old_password.response.old_lm_hash_enc_data) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (params->old_password.response.old_nt_hash_enc_length &&
+ !params->old_password.response.old_nt_hash_enc_data) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (params->old_password.response.old_nt_hash_enc_length == 0 &&
+ params->old_password.response.old_nt_hash_enc_data) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (params->new_password.response.lm_length &&
+ !params->new_password.response.lm_data) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (params->new_password.response.lm_length == 0 &&
+ params->new_password.response.lm_data) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (params->new_password.response.nt_length &&
+ !params->new_password.response.nt_data) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (params->new_password.response.nt_length == 0 &&
+ params->new_password.response.nt_data) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ strncpy(request.data.chng_pswd_auth_crap.user,
+ params->account_name,
+ sizeof(request.data.chng_pswd_auth_crap.user) - 1);
+
+ strncpy(request.data.chng_pswd_auth_crap.domain,
+ params->domain_name,
+ sizeof(request.data.chng_pswd_auth_crap.domain) - 1);
+
+ if (params->new_password.response.nt_data) {
+ memcpy(request.data.chng_pswd_auth_crap.new_nt_pswd,
+ params->new_password.response.nt_data,
+ request.data.chng_pswd_auth_crap.new_nt_pswd_len);
+ request.data.chng_pswd_auth_crap.new_nt_pswd_len =
+ params->new_password.response.nt_length;
+ }
+
+ if (params->new_password.response.lm_data) {
+ memcpy(request.data.chng_pswd_auth_crap.new_lm_pswd,
+ params->new_password.response.lm_data,
+ request.data.chng_pswd_auth_crap.new_lm_pswd_len);
+ request.data.chng_pswd_auth_crap.new_lm_pswd_len =
+ params->new_password.response.lm_length;
+ }
+
+ if (params->old_password.response.old_nt_hash_enc_data) {
+ memcpy(request.data.chng_pswd_auth_crap.old_nt_hash_enc,
+ params->old_password.response.old_nt_hash_enc_data,
+ request.data.chng_pswd_auth_crap.old_nt_hash_enc_len);
+ request.data.chng_pswd_auth_crap.old_nt_hash_enc_len =
+ params->old_password.response.old_nt_hash_enc_length;
+ }
+
+ if (params->old_password.response.old_lm_hash_enc_data) {
+ memcpy(request.data.chng_pswd_auth_crap.old_lm_hash_enc,
+ params->old_password.response.old_lm_hash_enc_data,
+ request.data.chng_pswd_auth_crap.old_lm_hash_enc_len);
+ request.data.chng_pswd_auth_crap.old_lm_hash_enc_len =
+ params->old_password.response.old_lm_hash_enc_length;
+ }
+
+ break;
+ default:
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ break;
+ }
+
+ if (cmd == 0) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ /* Send request */
+
+ wbc_status = wbcRequestResponse(cmd,
+ &request,
+ &response);
+ if (WBC_ERROR_IS_OK(wbc_status)) {
+ goto done;
+ }
+
+ /* Take the response above and return it to the caller */
+
+ if (response.data.auth.nt_status != 0) {
+ if (error) {
+ wbc_status = wbc_create_error_info(NULL,
+ &response,
+ error);
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ }
+
+ if (policy) {
+ wbc_status = wbc_create_password_policy_info(NULL,
+ &response,
+ policy);
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (reject_reason) {
+ *reject_reason = response.data.auth.reject_reason;
+ }
+
+ wbc_status = WBC_ERR_PWD_CHANGE_FAILED;
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ done:
+ return wbc_status;
+}
+
+/** @brief Change a password for a user
+ *
+ * @param username Name of user to authenticate
+ * @param old_password Old clear text password of user
+ * @param new_password New clear text password of user
+ *
+ * @return #wbcErr
+ **/
+
+wbcErr wbcChangeUserPassword(const char *username,
+ const char *old_password,
+ const char *new_password)
+{
+ wbcErr wbc_status = WBC_ERR_SUCCESS;
+ struct wbcChangePasswordParams params;
+
+ ZERO_STRUCT(params);
+
+ params.account_name = username;
+ params.level = WBC_CHANGE_PASSWORD_LEVEL_PLAIN;
+ params.old_password.plaintext = old_password;
+ params.new_password.plaintext = new_password;
+
+ wbc_status = wbcChangeUserPasswordEx(&params,
+ NULL,
+ NULL,
+ NULL);
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+done:
+ return wbc_status;
+}
diff --git a/source3/nsswitch/libwbclient/wbclient.c b/source3/nsswitch/libwbclient/wbclient.c
index 82decc2f78..bdde562a93 100644
--- a/source3/nsswitch/libwbclient/wbclient.c
+++ b/source3/nsswitch/libwbclient/wbclient.c
@@ -116,6 +116,8 @@ const char *wbcErrorString(wbcErr error)
return "WBC_ERR_UNKNOWN_GROUP";
case WBC_ERR_AUTH_ERROR:
return "WBC_ERR_AUTH_ERROR";
+ case WBC_ERR_PWD_CHANGE_FAILED:
+ return "WBC_ERR_PWD_CHANGE_FAILED";
}
return "unknown wbcErr value";
diff --git a/source3/nsswitch/libwbclient/wbclient.h b/source3/nsswitch/libwbclient/wbclient.h
index 2fefe0c072..cae3feec5b 100644
--- a/source3/nsswitch/libwbclient/wbclient.h
+++ b/source3/nsswitch/libwbclient/wbclient.h
@@ -44,7 +44,8 @@ enum _wbcErrType {
WBC_ERR_NSS_ERROR, /**< NSS_STATUS error **/
WBC_ERR_AUTH_ERROR, /**< Authentication failed **/
WBC_ERR_UNKNOWN_USER, /**< User account cannot be found */
- WBC_ERR_UNKNOWN_GROUP /**< Group account cannot be found */
+ WBC_ERR_UNKNOWN_GROUP, /**< Group account cannot be found */
+ WBC_ERR_PWD_CHANGE_FAILED /**< Password Change has failed */
};
typedef enum _wbcErrType wbcErr;
@@ -204,6 +205,41 @@ struct wbcAuthUserParams {
} password;
};
+/**
+ * @brief ChangePassword Parameters
+ **/
+
+struct wbcChangePasswordParams {
+ const char *account_name;
+ const char *domain_name;
+
+ uint32_t flags;
+
+ enum wbcChangePasswordLevel {
+ WBC_CHANGE_PASSWORD_LEVEL_PLAIN = 1,
+ WBC_CHANGE_PASSWORD_LEVEL_RESPONSE = 2
+ } level;
+
+ union {
+ const char *plaintext;
+ struct {
+ uint32_t old_nt_hash_enc_length;
+ uint8_t *old_nt_hash_enc_data;
+ uint32_t old_lm_hash_enc_length;
+ uint8_t *old_lm_hash_enc_data;
+ } response;
+ } old_password;
+ union {
+ const char *plaintext;
+ struct {
+ uint32_t nt_length;
+ uint8_t *nt_data;
+ uint32_t lm_length;
+ uint8_t *lm_data;
+ } response;
+ } new_password;
+};
+
/* wbcAuthUserParams->parameter_control */
#define WBC_MSV1_0_CLEARTEXT_PASSWORD_ALLOWED 0x00000002
@@ -304,6 +340,38 @@ struct wbcAuthErrorInfo {
char *display_string;
};
+/**
+ * @brief User Password Policy Information
+ **/
+
+/* wbcUserPasswordPolicyInfo->password_properties */
+
+#define WBC_DOMAIN_PASSWORD_COMPLEX 0x00000001
+#define WBC_DOMAIN_PASSWORD_NO_ANON_CHANGE 0x00000002
+#define WBC_DOMAIN_PASSWORD_NO_CLEAR_CHANGE 0x00000004
+#define WBC_DOMAIN_PASSWORD_LOCKOUT_ADMINS 0x00000008
+#define WBC_DOMAIN_PASSWORD_STORE_CLEARTEXT 0x00000010
+#define WBC_DOMAIN_REFUSE_PASSWORD_CHANGE 0x00000020
+
+struct wbcUserPasswordPolicyInfo {
+ uint32_t min_length_password;
+ uint32_t password_history;
+ uint32_t password_properties;
+ uint64_t expire;
+ uint64_t min_passwordage;
+};
+
+/**
+ * @brief Change Password Reject Reason
+ **/
+
+enum wbcPasswordChangeRejectReason {
+ WBC_PWD_CHANGE_REJECT_OTHER=0,
+ WBC_PWD_CHANGE_REJECT_TOO_SHORT=1,
+ WBC_PWD_CHANGE_REJECT_IN_HISTORY=2,
+ WBC_PWD_CHANGE_REJECT_COMPLEXITY=5
+};
+
/*
* DomainControllerInfo struct
*/
@@ -478,6 +546,14 @@ wbcErr wbcLogoffUser(const char *username,
uid_t uid,
const char *ccfilename);
+wbcErr wbcChangeUserPassword(const char *username,
+ const char *old_password,
+ const char *new_password);
+
+wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
+ struct wbcAuthErrorInfo **error,
+ enum wbcPasswordChangeRejectReason *reject_reason,
+ struct wbcUserPasswordPolicyInfo **policy);
/*
* Resolve functions
diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c
index 463d9233d0..60524d1d1b 100644
--- a/source3/nsswitch/wbinfo.c
+++ b/source3/nsswitch/wbinfo.c
@@ -1341,6 +1341,28 @@ static bool wbinfo_ping(void)
return WBC_ERROR_IS_OK(wbc_status);
}
+static bool wbinfo_change_user_password(const char *username)
+{
+ wbcErr wbc_status;
+ char *old_password = NULL;
+ char *new_password = NULL;
+
+ old_password = wbinfo_prompt_pass("old", username);
+ new_password = wbinfo_prompt_pass("new", username);
+
+ wbc_status = wbcChangeUserPassword(username, old_password, new_password);
+
+ /* Display response */
+
+ d_printf("Password change for user %s %s\n", username,
+ WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
+
+ SAFE_FREE(old_password);
+ SAFE_FREE(new_password);
+
+ return WBC_ERROR_IS_OK(wbc_status);
+}
+
/* Main program */
enum {
@@ -1360,7 +1382,8 @@ enum {
OPT_UID_INFO,
OPT_GROUP_INFO,
OPT_VERBOSE,
- OPT_ONLINESTATUS
+ OPT_ONLINESTATUS,
+ OPT_CHANGE_USER_PASSWORD
};
int main(int argc, char **argv, char **envp)
@@ -1427,6 +1450,7 @@ int main(int argc, char **argv, char **envp)
#endif
{ "separator", 0, POPT_ARG_NONE, 0, OPT_SEPARATOR, "Get the active winbind separator", NULL },
{ "verbose", 0, POPT_ARG_NONE, 0, OPT_VERBOSE, "Print additional information per command", NULL },
+ { "change-user-password", 0, POPT_ARG_STRING, &string_arg, OPT_CHANGE_USER_PASSWORD, "Change the password for a user", NULL },
POPT_COMMON_CONFIGFILE
POPT_COMMON_VERSION
POPT_TABLEEND
@@ -1707,6 +1731,14 @@ int main(int argc, char **argv, char **envp)
goto done;
}
break;
+ case OPT_CHANGE_USER_PASSWORD:
+ if (!wbinfo_change_user_password(string_arg)) {
+ d_fprintf(stderr, "Could not change user password "
+ "for user %s\n", string_arg);
+ goto done;
+ }
+ break;
+
/* generic configuration options */
case OPT_DOMAIN_NAME:
break;
diff --git a/source3/utils/net_dom.c b/source3/utils/net_dom.c
index f13b9c23d0..5544cf8a2d 100644
--- a/source3/utils/net_dom.c
+++ b/source3/utils/net_dom.c
@@ -37,8 +37,8 @@ static int net_dom_unjoin(struct net_context *c, int argc, const char **argv)
const char *server_name = NULL;
const char *account = NULL;
const char *password = NULL;
- uint32_t unjoin_flags = WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE |
- WKSSVC_JOIN_FLAGS_JOIN_TYPE;
+ uint32_t unjoin_flags = NETSETUP_ACCT_DELETE |
+ NETSETUP_JOIN_DOMAIN;
struct cli_state *cli = NULL;
bool do_reboot = false;
NTSTATUS ntstatus;
@@ -125,8 +125,8 @@ static int net_dom_join(struct net_context *c, int argc, const char **argv)
const char *account_ou = NULL;
const char *Account = NULL;
const char *password = NULL;
- uint32_t join_flags = WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
- WKSSVC_JOIN_FLAGS_JOIN_TYPE;
+ uint32_t join_flags = NETSETUP_ACCT_CREATE |
+ NETSETUP_JOIN_DOMAIN;
struct cli_state *cli = NULL;
bool do_reboot = false;
NTSTATUS ntstatus;
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 347ddd039f..6db5bc753b 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -658,135 +658,37 @@ static int rpc_user_add(struct net_context *c, int argc, const char **argv)
/**
* Rename a user on a remote RPC server.
*
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passed through.
- *
- * @param domain_sid The domain sid acquired from the remote server.
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destroyed on completion of the function.
* @param argc Standard main() style argc.
* @param argv Standard main() style argv. Initial components are already
* stripped.
*
- * @return Normal NTSTATUS return.
+ * @return A shell status integer (0 for success).
**/
-static NTSTATUS rpc_user_rename_internals(struct net_context *c,
- const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- struct rpc_pipe_client *pipe_hnd,
- TALLOC_CTX *mem_ctx,
- int argc,
- const char **argv)
+static int rpc_user_rename(struct net_context *c, int argc, const char **argv)
{
- POLICY_HND connect_pol, domain_pol, user_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 info_level = 7;
- const char *old_name, *new_name;
- struct samr_Ids user_rids, name_types;
- struct lsa_String lsa_acct_name;
- union samr_UserInfo *info = NULL;
+ NET_API_STATUS status;
+ struct USER_INFO_0 u0;
+ uint32_t parm_err = 0;
if (argc != 2 || c->display_usage) {
rpc_user_usage(c, argc, argv);
- return NT_STATUS_OK;
- }
-
- old_name = argv[0];
- new_name = argv[1];
-
- /* Get sam policy handle */
-
- result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
- pipe_hnd->desthost,
- MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Get domain policy handle */
-
- result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
- &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- CONST_DISCARD(struct dom_sid2 *, domain_sid),
- &domain_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- init_lsa_String(&lsa_acct_name, old_name);
-
- result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
- &domain_pol,
- 1,
- &lsa_acct_name,
- &user_rids,
- &name_types);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Open domain user */
- result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
- &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- user_rids.ids[0],
- &user_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Query user info */
- result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx,
- &user_pol,
- info_level,
- &info);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
+ return 0;
}
- init_samr_user_info7(&info->info7, new_name);
+ u0.usri0_name = argv[1];
- /* Set new name */
- result = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx,
- &user_pol,
- info_level,
- info);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- done:
- if (!NT_STATUS_IS_OK(result)) {
- d_fprintf(stderr, "Failed to rename user from %s to %s - %s\n", old_name, new_name,
- nt_errstr(result));
+ status = NetUserSetInfo(c->opt_host, argv[0],
+ 0, (uint8_t *)&u0, &parm_err);
+ if (status) {
+ d_fprintf(stderr, "Failed to rename user from %s to %s - %s\n",
+ argv[0], argv[1],
+ libnetapi_get_error_string(c->netapi_ctx, status));
} else {
- d_printf("Renamed user from %s to %s\n", old_name, new_name);
+ d_printf("Renamed user from %s to %s\n", argv[0], argv[1]);
}
- return result;
-}
-/**
- * Rename a user on a remote RPC server.
- *
- * @param argc Standard main() style argc.
- * @param argv Standard main() style argv. Initial components are already
- * stripped.
- *
- * @return A shell status integer (0 for success).
- **/
-
-static int rpc_user_rename(struct net_context *c, int argc, const char **argv)
-{
- return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
- rpc_user_rename_internals, argc, argv);
+ return status;
}
/**
@@ -823,271 +725,93 @@ static int rpc_user_delete(struct net_context *c, int argc, const char **argv)
}
/**
- * Set a password for a user on a remote RPC server.
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passed through.
+ * Set a user's password on a remote RPC server.
*
- * @param domain_sid The domain sid acquired from the remote server.
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destroyed on completion of the function.
* @param argc Standard main() style argc.
* @param argv Standard main() style argv. Initial components are already
* stripped.
*
- * @return Normal NTSTATUS return.
+ * @return A shell status integer (0 for success).
**/
-static NTSTATUS rpc_user_password_internals(struct net_context *c,
- const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- struct rpc_pipe_client *pipe_hnd,
- TALLOC_CTX *mem_ctx,
- int argc,
- const char **argv)
+static int rpc_user_password(struct net_context *c, int argc, const char **argv)
{
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- POLICY_HND connect_pol, domain_pol, user_pol;
- const char *user;
- const char *new_password;
+ NET_API_STATUS status;
char *prompt = NULL;
- union samr_UserInfo info;
- struct samr_CryptPassword crypt_pwd;
+ struct USER_INFO_1003 u1003;
+ uint32_t parm_err = 0;
if (argc < 1 || c->display_usage) {
rpc_user_usage(c, argc, argv);
- return NT_STATUS_OK;
+ return 0;
}
- user = argv[0];
-
if (argv[1]) {
- new_password = argv[1];
+ u1003.usri1003_password = argv[1];
} else {
- asprintf(&prompt, "Enter new password for %s:", user);
- new_password = getpass(prompt);
+ asprintf(&prompt, "Enter new password for %s:", argv[0]);
+ u1003.usri1003_password = getpass(prompt);
SAFE_FREE(prompt);
}
- /* Get sam policy and domain handles */
-
- result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
- pipe_hnd->desthost,
- MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
- &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- CONST_DISCARD(struct dom_sid2 *, domain_sid),
- &domain_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Get handle on user */
-
- {
- struct samr_Ids user_rids, name_types;
- struct lsa_String lsa_acct_name;
-
- init_lsa_String(&lsa_acct_name, user);
-
- result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
- &domain_pol,
- 1,
- &lsa_acct_name,
- &user_rids,
- &name_types);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
- &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- user_rids.ids[0],
- &user_pol);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
- }
-
- /* Set password on account */
-
- init_samr_CryptPassword(new_password,
- &cli->user_session_key,
- &crypt_pwd);
-
- init_samr_user_info24(&info.info24, crypt_pwd.data, 24);
-
- result = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx,
- &user_pol,
- 24,
- &info);
-
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
+ status = NetUserSetInfo(c->opt_host, argv[0], 1003, (uint8_t *)&u1003, &parm_err);
/* Display results */
+ if (status != 0) {
+ d_fprintf(stderr, "Failed to set password for '%s' with: %s.\n",
+ argv[0], libnetapi_get_error_string(c->netapi_ctx,
+ status));
+ return -1;
+ }
- done:
- return result;
-
+ return 0;
}
/**
- * Set a user's password on a remote RPC server.
+ * List a user's groups from a remote RPC server.
*
* @param argc Standard main() style argc.
* @param argv Standard main() style argv. Initial components are already
* stripped.
*
- * @return A shell status integer (0 for success).
+ * @return A shell status integer (0 for success)
**/
-static int rpc_user_password(struct net_context *c, int argc, const char **argv)
-{
- return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
- rpc_user_password_internals, argc, argv);
-}
-
-/**
- * List user's groups on a remote RPC server.
- *
- * All parameters are provided by the run_rpc_command function, except for
- * argc, argv which are passed through.
- *
- * @param domain_sid The domain sid acquired from the remote server.
- * @param cli A cli_state connected to the server.
- * @param mem_ctx Talloc context, destroyed on completion of the function.
- * @param argc Standard main() style argc.
- * @param argv Standard main() style argv. Initial components are already
- * stripped.
- *
- * @return Normal NTSTATUS return.
- **/
+static int rpc_user_info(struct net_context *c, int argc, const char **argv)
-static NTSTATUS rpc_user_info_internals(struct net_context *c,
- const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- struct rpc_pipe_client *pipe_hnd,
- TALLOC_CTX *mem_ctx,
- int argc,
- const char **argv)
{
- POLICY_HND connect_pol, domain_pol, user_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ NET_API_STATUS status;
+ struct GROUP_USERS_INFO_0 *u0 = NULL;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
int i;
- struct samr_RidWithAttributeArray *rid_array = NULL;
- struct lsa_Strings names;
- struct samr_Ids types;
- uint32_t *lrids = NULL;
- struct samr_Ids rids, name_types;
- struct lsa_String lsa_acct_name;
if (argc < 1 || c->display_usage) {
rpc_user_usage(c, argc, argv);
- return NT_STATUS_OK;
+ return 0;
}
- /* Get sam policy handle */
-
- result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
- pipe_hnd->desthost,
- MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- /* Get domain policy handle */
-
- result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
- &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- CONST_DISCARD(struct dom_sid2 *, domain_sid),
- &domain_pol);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- /* Get handle on user */
-
- init_lsa_String(&lsa_acct_name, argv[0]);
-
- result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
- &domain_pol,
- 1,
- &lsa_acct_name,
- &rids,
- &name_types);
-
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
- &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- rids.ids[0],
- &user_pol);
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- result = rpccli_samr_GetGroupsForUser(pipe_hnd, mem_ctx,
- &user_pol,
- &rid_array);
-
- if (!NT_STATUS_IS_OK(result)) goto done;
-
- /* Look up rids */
-
- if (rid_array->count) {
- if ((lrids = TALLOC_ARRAY(mem_ctx, uint32, rid_array->count)) == NULL) {
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- for (i = 0; i < rid_array->count; i++)
- lrids[i] = rid_array->rids[i].rid;
-
- result = rpccli_samr_LookupRids(pipe_hnd, mem_ctx,
- &domain_pol,
- rid_array->count,
- lrids,
- &names,
- &types);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Display results */
-
- for (i = 0; i < names.count; i++)
- printf("%s\n", names.names[i].string);
+ status = NetUserGetGroups(c->opt_host,
+ argv[0],
+ 0,
+ (uint8_t **)&u0,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries);
+ if (status != 0) {
+ d_fprintf(stderr, "Failed to get groups for '%s' with: %s.\n",
+ argv[0], libnetapi_get_error_string(c->netapi_ctx,
+ status));
+ return -1;
}
- done:
- return result;
-}
-/**
- * List a user's groups from a remote RPC server.
- *
- * @param argc Standard main() style argc.
- * @param argv Standard main() style argv. Initial components are already
- * stripped.
- *
- * @return A shell status integer (0 for success)
- **/
+ for (i=0; i < entries_read; i++) {
+ printf("%s\n", u0->grui0_name);
+ u0++;
+ }
-static int rpc_user_info(struct net_context *c, int argc, const char **argv)
-{
- return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
- rpc_user_info_internals, argc, argv);
+ return 0;
}
/**
@@ -1106,80 +830,54 @@ static int rpc_user_info(struct net_context *c, int argc, const char **argv)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS rpc_user_list_internals(struct net_context *c,
- const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- struct rpc_pipe_client *pipe_hnd,
- TALLOC_CTX *mem_ctx,
- int argc,
- const char **argv)
+static int rpc_user_list(struct net_context *c, int argc, const char **argv)
{
- POLICY_HND connect_pol, domain_pol;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 start_idx=0, num_entries, i, loop_count = 0;
-
- /* Get sam policy handle */
-
- result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
- pipe_hnd->desthost,
- MAXIMUM_ALLOWED_ACCESS,
- &connect_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
-
- /* Get domain policy handle */
-
- result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
- &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- CONST_DISCARD(struct dom_sid2 *, domain_sid),
- &domain_pol);
- if (!NT_STATUS_IS_OK(result)) {
- goto done;
- }
+ NET_API_STATUS status;
+ uint32_t start_idx=0, num_entries, i, loop_count = 0;
+ struct NET_DISPLAY_USER *info = NULL;
+ void *buffer = NULL;
/* Query domain users */
if (c->opt_long_list_entries)
d_printf("\nUser name Comment"
"\n-----------------------------\n");
do {
- const char *user = NULL;
- const char *desc = NULL;
- uint32 max_entries, max_size;
- uint32_t total_size, returned_size;
- union samr_DispInfo info;
+ uint32_t max_entries, max_size;
get_query_dispinfo_params(
loop_count, &max_entries, &max_size);
- result = rpccli_samr_QueryDisplayInfo(pipe_hnd, mem_ctx,
- &domain_pol,
- 1,
- start_idx,
- max_entries,
- max_size,
- &total_size,
- &returned_size,
- &info);
- loop_count++;
- start_idx += info.info1.count;
- num_entries = info.info1.count;
+ status = NetQueryDisplayInformation(c->opt_host,
+ 1,
+ start_idx,
+ max_entries,
+ max_size,
+ &num_entries,
+ &buffer);
+ if (status != 0 && status != ERROR_MORE_DATA) {
+ return status;
+ }
+
+ info = (struct NET_DISPLAY_USER *)buffer;
for (i = 0; i < num_entries; i++) {
- user = info.info1.entries[i].account_name.string;
- if (c->opt_long_list_entries)
- desc = info.info1.entries[i].description.string;
+
if (c->opt_long_list_entries)
- printf("%-21.21s %s\n", user, desc);
+ printf("%-21.21s %s\n", info->usri1_name,
+ info->usri1_comment);
else
- printf("%s\n", user);
+ printf("%s\n", info->usri1_name);
+ info++;
}
- } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
- done:
- return result;
+ NetApiBufferFree(buffer);
+
+ loop_count++;
+ start_idx += num_entries;
+
+ } while (status == ERROR_MORE_DATA);
+
+ return status;
}
/**
@@ -1256,9 +954,7 @@ int net_rpc_user(struct net_context *c, int argc, const char **argv)
return 0;
}
- return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
- rpc_user_list_internals,
- argc, argv);
+ return rpc_user_list(c, argc, argv);
}
return net_run_function(c, argc, argv, "net rpc user", func);
@@ -1270,9 +966,7 @@ static NTSTATUS rpc_sh_user_list(struct net_context *c,
struct rpc_pipe_client *pipe_hnd,
int argc, const char **argv)
{
- return rpc_user_list_internals(c, ctx->domain_sid, ctx->domain_name,
- ctx->cli, pipe_hnd, mem_ctx,
- argc, argv);
+ return werror_to_ntstatus(W_ERROR(rpc_user_list(c, argc, argv)));
}
static NTSTATUS rpc_sh_user_info(struct net_context *c,
@@ -1281,9 +975,7 @@ static NTSTATUS rpc_sh_user_info(struct net_context *c,
struct rpc_pipe_client *pipe_hnd,
int argc, const char **argv)
{
- return rpc_user_info_internals(c, ctx->domain_sid, ctx->domain_name,
- ctx->cli, pipe_hnd, mem_ctx,
- argc, argv);
+ return werror_to_ntstatus(W_ERROR(rpc_user_info(c, argc, argv)));
}
static NTSTATUS rpc_sh_handle_user(struct net_context *c,
diff --git a/source3/utils/net_rpc_shell.c b/source3/utils/net_rpc_shell.c
index c6051dc976..3aaed1ed18 100644
--- a/source3/utils/net_rpc_shell.c
+++ b/source3/utils/net_rpc_shell.c
@@ -217,6 +217,15 @@ int net_rpc_shell(struct net_context *c, int argc, const char **argv)
return -1;
}
+ if (libnetapi_init(&c->netapi_ctx) != 0) {
+ return -1;
+ }
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
+ libnetapi_set_use_kerberos(c->netapi_ctx);
+ }
+
ctx = TALLOC_P(NULL, struct rpc_sh_ctx);
if (ctx == NULL) {
d_fprintf(stderr, "talloc failed\n");