svn commit: samba r25040 - in branches: SAMBA_3_2/source/lib SAMBA_3_2/source/utils SAMBA_3_2_0/source/lib SAMBA_3_2_0/source/utils

vlendec at samba.org vlendec at samba.org
Sat Sep 8 20:30:52 GMT 2007


Author: vlendec
Date: 2007-09-08 20:30:51 +0000 (Sat, 08 Sep 2007)
New Revision: 25040

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=25040

Log:
Add "net sam rights"

Not strictly in the SAM, but close enough. This command acts directly on
the local tdb, no running smbd required

This also changes the root-only check to a warning

Modified:
   branches/SAMBA_3_2/source/lib/privileges.c
   branches/SAMBA_3_2/source/lib/util_sid.c
   branches/SAMBA_3_2/source/utils/net_sam.c
   branches/SAMBA_3_2_0/source/lib/privileges.c
   branches/SAMBA_3_2_0/source/lib/util_sid.c
   branches/SAMBA_3_2_0/source/utils/net_sam.c


Changeset:
Modified: branches/SAMBA_3_2/source/lib/privileges.c
===================================================================
--- branches/SAMBA_3_2/source/lib/privileges.c	2007-09-08 20:03:19 UTC (rev 25039)
+++ branches/SAMBA_3_2/source/lib/privileges.c	2007-09-08 20:30:51 UTC (rev 25040)
@@ -31,6 +31,7 @@
 } SID_LIST;
 
 typedef struct {
+	TALLOC_CTX *mem_ctx;
 	SE_PRIV privilege;
 	SID_LIST sids;
 } PRIV_SID_LIST;
@@ -183,7 +184,8 @@
 		return 0;
 	}
 
-	if (!add_sid_to_array( NULL, &sid, &priv->sids.list, &priv->sids.count )) {
+	if (!add_sid_to_array( priv->mem_ctx, &sid, &priv->sids.list,
+			       &priv->sids.count )) {
 		return 0;
 	}
 	
@@ -217,6 +219,35 @@
 	return NT_STATUS_OK;
 }
 
+/*********************************************************************
+ Retrieve list of SIDs granted a particular privilege
+*********************************************************************/
+
+NTSTATUS privilege_enum_sids(const SE_PRIV *mask, TALLOC_CTX *mem_ctx,
+			     DOM_SID **sids, int *num_sids)
+{
+	TDB_CONTEXT *tdb = get_account_pol_tdb();
+	PRIV_SID_LIST priv;
+
+	if (!tdb) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	ZERO_STRUCT(priv);
+
+	se_priv_copy(&priv.privilege, mask);
+	priv.mem_ctx = mem_ctx;
+
+	tdb_traverse( tdb, priv_traverse_fn, &priv);
+
+	/* give the memory away; caller will free */
+
+	*sids      = priv.sids.list;
+	*num_sids  = priv.sids.count;
+
+	return NT_STATUS_OK;
+}
+
 /***************************************************************************
  Add privilege to sid
 ****************************************************************************/

Modified: branches/SAMBA_3_2/source/lib/util_sid.c
===================================================================
--- branches/SAMBA_3_2/source/lib/util_sid.c	2007-09-08 20:03:19 UTC (rev 25039)
+++ branches/SAMBA_3_2/source/lib/util_sid.c	2007-09-08 20:30:51 UTC (rev 25040)
@@ -207,6 +207,13 @@
 	return sid_str;
 }
 
+char *sid_string_tos(const DOM_SID *sid)
+{
+	fstring sid_str;
+	sid_to_string(sid_str, sid);
+	return talloc_strdup(talloc_tos(), sid_str);
+}
+
 /*****************************************************************
  Convert a string to a SID. Returns True on success, False on fail.
 *****************************************************************/  

Modified: branches/SAMBA_3_2/source/utils/net_sam.c
===================================================================
--- branches/SAMBA_3_2/source/utils/net_sam.c	2007-09-08 20:03:19 UTC (rev 25039)
+++ branches/SAMBA_3_2/source/utils/net_sam.c	2007-09-08 20:30:51 UTC (rev 25040)
@@ -504,6 +504,138 @@
         return net_run_function2(argc, argv, "net sam policy", func);
 }
 
+extern PRIVS privs[];
+
+static int net_sam_rights_list(int argc, const char **argv)
+{
+	SE_PRIV mask;
+
+	if (argc > 1) {
+		d_fprintf(stderr, "usage: net sam rights list [name]\n");
+		return -1;
+	}
+
+	if (argc == 0) {
+		int i;
+		int num = count_all_privileges();
+
+		for (i=0; i<num; i++) {
+			d_printf("%s\n", privs[i].name);
+		}
+		return 0;
+	}
+
+	if (se_priv_from_name(argv[0], &mask)) {
+		DOM_SID *sids;
+		int i, num_sids;
+		NTSTATUS status;
+
+		status = privilege_enum_sids(&mask, talloc_tos(),
+					     &sids, &num_sids);
+		if (!NT_STATUS_IS_OK(status)) {
+			d_fprintf(stderr, "Could not list rights: %s\n",
+				  nt_errstr(status));
+			return -1;
+		}
+
+		for (i=0; i<num_sids; i++) {
+			const char *dom, *name;
+			enum lsa_SidType type;
+
+			if (lookup_sid(talloc_tos(), &sids[i], &dom, &name,
+				       &type)) {
+				d_printf("%s\\%s\n", dom, name);
+			}
+			else {
+				d_printf("%s\n", sid_string_tos(&sids[i]));
+			}
+		}
+		return 0;
+	}
+
+	return -1;
+}
+
+static int net_sam_rights_grant(int argc, const char **argv)
+{
+	DOM_SID sid;
+	enum lsa_SidType type;
+	const char *dom, *name;
+	SE_PRIV mask;
+
+	if (argc != 2) {
+		d_fprintf(stderr, "usage: net sam rights grant <name> "
+			  "<right>\n");
+		return -1;
+	}
+
+	if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ISOLATED,
+			 &dom, &name, &sid, &type)) {
+		d_fprintf(stderr, "Could not find name %s\n", argv[0]);
+		return -1;
+	}
+
+	if (!se_priv_from_name(argv[1], &mask)) {
+		d_fprintf(stderr, "%s unknown\n", argv[1]);
+		return -1;
+	}
+
+	if (!grant_privilege(&sid, &mask)) {
+		d_fprintf(stderr, "Could not grant privilege\n");
+		return -1;
+	}
+
+	d_printf("Granted %s to %s\\%s\n", argv[1], dom, name);
+	return 0;
+}
+
+static int net_sam_rights_revoke(int argc, const char **argv)
+{
+	DOM_SID sid;
+	enum lsa_SidType type;
+	const char *dom, *name;
+	SE_PRIV mask;
+
+	if (argc != 2) {
+		d_fprintf(stderr, "usage: net sam rights revoke <name> "
+			  "<right>\n");
+		return -1;
+	}
+
+	if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ISOLATED,
+			 &dom, &name, &sid, &type)) {
+		d_fprintf(stderr, "Could not find name %s\n", argv[0]);
+		return -1;
+	}
+
+	if (!se_priv_from_name(argv[1], &mask)) {
+		d_fprintf(stderr, "%s unknown\n", argv[1]);
+		return -1;
+	}
+
+	if (!revoke_privilege(&sid, &mask)) {
+		d_fprintf(stderr, "Could not revoke privilege\n");
+		return -1;
+	}
+
+	d_printf("Revoked %s from %s\\%s\n", argv[1], dom, name);
+	return 0;
+}
+
+static int net_sam_rights(int argc, const char **argv)
+{
+	struct functable2 func[] = {
+		{ "list", net_sam_rights_list,
+		  "List possible user rights" },
+		{ "grant", net_sam_rights_grant,
+		  "Grant a right" },
+		{ "revoke", net_sam_rights_revoke,
+		  "Revoke a right" },
+		{ NULL }
+	};
+        return net_run_function2(argc, argv, "net sam rights", func);
+}
+
 /*
  * Map a unix group to a domain group
  */
@@ -1521,6 +1653,8 @@
 		  "Set details of a SAM account" },
 		{ "policy", net_sam_policy,
 		  "Set account policies" },
+		{ "rights", net_sam_rights,
+		  "Manipulate user privileges" },
 #ifdef HAVE_LDAP
 		{ "provision", net_sam_provision,
 		  "Provision a clean User Database" },
@@ -1528,11 +1662,9 @@
 		{ NULL, NULL, NULL }
 	};
 
-	/* we shouldn't have silly checks like this */
 	if (getuid() != 0) {
-		d_fprintf(stderr, "You must be root to edit the SAM "
-			  "directly.\n");
-		return -1;
+		d_fprintf(stderr, "You are not root, most things won't "
+			  "work\n");
 	}
 	
 	return net_run_function2(argc, argv, "net sam", func);

Modified: branches/SAMBA_3_2_0/source/lib/privileges.c
===================================================================
--- branches/SAMBA_3_2_0/source/lib/privileges.c	2007-09-08 20:03:19 UTC (rev 25039)
+++ branches/SAMBA_3_2_0/source/lib/privileges.c	2007-09-08 20:30:51 UTC (rev 25040)
@@ -31,6 +31,7 @@
 } SID_LIST;
 
 typedef struct {
+	TALLOC_CTX *mem_ctx;
 	SE_PRIV privilege;
 	SID_LIST sids;
 } PRIV_SID_LIST;
@@ -183,7 +184,8 @@
 		return 0;
 	}
 
-	if (!add_sid_to_array( NULL, &sid, &priv->sids.list, &priv->sids.count )) {
+	if (!add_sid_to_array( priv->mem_ctx, &sid, &priv->sids.list,
+			       &priv->sids.count )) {
 		return 0;
 	}
 	
@@ -217,6 +219,35 @@
 	return NT_STATUS_OK;
 }
 
+/*********************************************************************
+ Retrieve list of SIDs granted a particular privilege
+*********************************************************************/
+
+NTSTATUS privilege_enum_sids(const SE_PRIV *mask, TALLOC_CTX *mem_ctx,
+			     DOM_SID **sids, int *num_sids)
+{
+	TDB_CONTEXT *tdb = get_account_pol_tdb();
+	PRIV_SID_LIST priv;
+
+	if (!tdb) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	ZERO_STRUCT(priv);
+
+	se_priv_copy(&priv.privilege, mask);
+	priv.mem_ctx = mem_ctx;
+
+	tdb_traverse( tdb, priv_traverse_fn, &priv);
+
+	/* give the memory away; caller will free */
+
+	*sids      = priv.sids.list;
+	*num_sids  = priv.sids.count;
+
+	return NT_STATUS_OK;
+}
+
 /***************************************************************************
  Add privilege to sid
 ****************************************************************************/

Modified: branches/SAMBA_3_2_0/source/lib/util_sid.c
===================================================================
--- branches/SAMBA_3_2_0/source/lib/util_sid.c	2007-09-08 20:03:19 UTC (rev 25039)
+++ branches/SAMBA_3_2_0/source/lib/util_sid.c	2007-09-08 20:30:51 UTC (rev 25040)
@@ -207,6 +207,13 @@
 	return sid_str;
 }
 
+char *sid_string_tos(const DOM_SID *sid)
+{
+	fstring sid_str;
+	sid_to_string(sid_str, sid);
+	return talloc_strdup(talloc_tos(), sid_str);
+}
+
 /*****************************************************************
  Convert a string to a SID. Returns True on success, False on fail.
 *****************************************************************/  

Modified: branches/SAMBA_3_2_0/source/utils/net_sam.c
===================================================================
--- branches/SAMBA_3_2_0/source/utils/net_sam.c	2007-09-08 20:03:19 UTC (rev 25039)
+++ branches/SAMBA_3_2_0/source/utils/net_sam.c	2007-09-08 20:30:51 UTC (rev 25040)
@@ -504,6 +504,138 @@
         return net_run_function2(argc, argv, "net sam policy", func);
 }
 
+extern PRIVS privs[];
+
+static int net_sam_rights_list(int argc, const char **argv)
+{
+	SE_PRIV mask;
+
+	if (argc > 1) {
+		d_fprintf(stderr, "usage: net sam rights list [name]\n");
+		return -1;
+	}
+
+	if (argc == 0) {
+		int i;
+		int num = count_all_privileges();
+
+		for (i=0; i<num; i++) {
+			d_printf("%s\n", privs[i].name);
+		}
+		return 0;
+	}
+
+	if (se_priv_from_name(argv[0], &mask)) {
+		DOM_SID *sids;
+		int i, num_sids;
+		NTSTATUS status;
+
+		status = privilege_enum_sids(&mask, talloc_tos(),
+					     &sids, &num_sids);
+		if (!NT_STATUS_IS_OK(status)) {
+			d_fprintf(stderr, "Could not list rights: %s\n",
+				  nt_errstr(status));
+			return -1;
+		}
+
+		for (i=0; i<num_sids; i++) {
+			const char *dom, *name;
+			enum lsa_SidType type;
+
+			if (lookup_sid(talloc_tos(), &sids[i], &dom, &name,
+				       &type)) {
+				d_printf("%s\\%s\n", dom, name);
+			}
+			else {
+				d_printf("%s\n", sid_string_tos(&sids[i]));
+			}
+		}
+		return 0;
+	}
+
+	return -1;
+}
+
+static int net_sam_rights_grant(int argc, const char **argv)
+{
+	DOM_SID sid;
+	enum lsa_SidType type;
+	const char *dom, *name;
+	SE_PRIV mask;
+
+	if (argc != 2) {
+		d_fprintf(stderr, "usage: net sam rights grant <name> "
+			  "<right>\n");
+		return -1;
+	}
+
+	if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ISOLATED,
+			 &dom, &name, &sid, &type)) {
+		d_fprintf(stderr, "Could not find name %s\n", argv[0]);
+		return -1;
+	}
+
+	if (!se_priv_from_name(argv[1], &mask)) {
+		d_fprintf(stderr, "%s unknown\n", argv[1]);
+		return -1;
+	}
+
+	if (!grant_privilege(&sid, &mask)) {
+		d_fprintf(stderr, "Could not grant privilege\n");
+		return -1;
+	}
+
+	d_printf("Granted %s to %s\\%s\n", argv[1], dom, name);
+	return 0;
+}
+
+static int net_sam_rights_revoke(int argc, const char **argv)
+{
+	DOM_SID sid;
+	enum lsa_SidType type;
+	const char *dom, *name;
+	SE_PRIV mask;
+
+	if (argc != 2) {
+		d_fprintf(stderr, "usage: net sam rights revoke <name> "
+			  "<right>\n");
+		return -1;
+	}
+
+	if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ISOLATED,
+			 &dom, &name, &sid, &type)) {
+		d_fprintf(stderr, "Could not find name %s\n", argv[0]);
+		return -1;
+	}
+
+	if (!se_priv_from_name(argv[1], &mask)) {
+		d_fprintf(stderr, "%s unknown\n", argv[1]);
+		return -1;
+	}
+
+	if (!revoke_privilege(&sid, &mask)) {
+		d_fprintf(stderr, "Could not revoke privilege\n");
+		return -1;
+	}
+
+	d_printf("Revoked %s from %s\\%s\n", argv[1], dom, name);
+	return 0;
+}
+
+static int net_sam_rights(int argc, const char **argv)
+{
+	struct functable2 func[] = {
+		{ "list", net_sam_rights_list,
+		  "List possible user rights" },
+		{ "grant", net_sam_rights_grant,
+		  "Grant a right" },
+		{ "revoke", net_sam_rights_revoke,
+		  "Revoke a right" },
+		{ NULL }
+	};
+        return net_run_function2(argc, argv, "net sam rights", func);
+}
+
 /*
  * Map a unix group to a domain group
  */
@@ -1521,6 +1653,8 @@
 		  "Set details of a SAM account" },
 		{ "policy", net_sam_policy,
 		  "Set account policies" },
+		{ "rights", net_sam_rights,
+		  "Manipulate user privileges" },
 #ifdef HAVE_LDAP
 		{ "provision", net_sam_provision,
 		  "Provision a clean User Database" },
@@ -1528,11 +1662,9 @@
 		{ NULL, NULL, NULL }
 	};
 
-	/* we shouldn't have silly checks like this */
 	if (getuid() != 0) {
-		d_fprintf(stderr, "You must be root to edit the SAM "
-			  "directly.\n");
-		return -1;
+		d_fprintf(stderr, "You are not root, most things won't "
+			  "work\n");
 	}
 	
 	return net_run_function2(argc, argv, "net sam", func);



More information about the samba-cvs mailing list