summaryrefslogtreecommitdiff
path: root/source3/lib/util_sid.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib/util_sid.c')
-rw-r--r--source3/lib/util_sid.c290
1 files changed, 289 insertions, 1 deletions
diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c
index 9e5154d259..f2f7b3c8ae 100644
--- a/source3/lib/util_sid.c
+++ b/source3/lib/util_sid.c
@@ -335,7 +335,7 @@ BOOL sid_split_rid(DOM_SID *sid, uint32 *rid)
Copies a sid
*****************************************************************/
-void sid_copy(DOM_SID *dst, DOM_SID *src)
+void sid_copy(DOM_SID *dst, const DOM_SID *src)
{
int i;
@@ -424,3 +424,291 @@ size_t sid_size(DOM_SID *sid)
return sid->num_auths * sizeof(uint32) + 8;
}
+
+static BOOL read_sid_from_file(int fd, char *sid_file, DOM_SID *sid)
+{
+ fstring fline;
+ fstring sid_str;
+
+ memset(fline, '\0', sizeof(fline));
+
+ if (read(fd, fline, sizeof(fline) -1 ) < 0) {
+ DEBUG(0,("unable to read file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ return False;
+ }
+
+ /*
+ * Convert to the machine SID.
+ */
+
+ fline[sizeof(fline)-1] = '\0';
+ if (!string_to_sid(sid, fline)) {
+ DEBUG(0,("unable to read sid.\n"));
+ return False;
+ }
+
+ sid_to_string(sid_str, sid);
+ DEBUG(5,("read_sid_from_file: sid %s\n", sid_str));
+
+ return True;
+}
+
+/****************************************************************************
+ Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
+ not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
+****************************************************************************/
+BOOL read_sid(char *sam_name, DOM_SID *sid)
+{
+ int fd;
+ char *p;
+ pstring sid_file;
+ fstring file_name;
+ SMB_STRUCT_STAT st;
+
+ pstrcpy(sid_file, lp_smb_passwd_file());
+
+ DEBUG(10,("read_sid: Domain: %s\n", sam_name));
+
+ if (sid_file[0] == 0)
+ {
+ DEBUG(0,("cannot find smb passwd file\n"));
+ return False;
+ }
+
+ p = strrchr(sid_file, '/');
+ if (p != NULL)
+ {
+ *++p = '\0';
+ }
+
+ if (!directory_exist(sid_file, NULL))
+ {
+ if (mkdir(sid_file, 0700) != 0)
+ {
+ DEBUG(0,("can't create private directory %s : %s\n",
+ sid_file, strerror(errno)));
+ return False;
+ }
+ }
+
+ slprintf(file_name, sizeof(file_name)-1, "%s.SID", sam_name);
+ strupper(file_name);
+ pstrcat(sid_file, file_name);
+
+ if ((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
+ DEBUG(0,("unable to open or create file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ return False;
+ }
+
+ /*
+ * Check if the file contains data.
+ */
+
+ if (sys_fstat(fd, &st) < 0) {
+ DEBUG(0,("unable to stat file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+
+ if (st.st_size == 0)
+ {
+ close(fd);
+ return False;
+ }
+
+ /*
+ * We have a valid SID - read it.
+ */
+
+ if (!read_sid_from_file(fd, sid_file, sid))
+ {
+ DEBUG(0,("unable to read file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+ close(fd);
+ return True;
+}
+
+
+/****************************************************************************
+ Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
+ not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
+****************************************************************************/
+BOOL write_sid(char *sam_name, DOM_SID *sid)
+{
+ int fd;
+ char *p;
+ pstring sid_file;
+ fstring sid_string;
+ fstring file_name;
+ SMB_STRUCT_STAT st;
+
+ pstrcpy(sid_file, lp_smb_passwd_file());
+ sid_to_string(sid_string, sid);
+
+ DEBUG(10,("write_sid: Domain: %s SID: %s\n", sam_name, sid_string));
+ fstrcat(sid_string, "\n");
+
+ if (sid_file[0] == 0)
+ {
+ DEBUG(0,("cannot find smb passwd file\n"));
+ return False;
+ }
+
+ p = strrchr(sid_file, '/');
+ if (p != NULL)
+ {
+ *++p = '\0';
+ }
+
+ if (!directory_exist(sid_file, NULL)) {
+ if (mkdir(sid_file, 0700) != 0) {
+ DEBUG(0,("can't create private directory %s : %s\n",
+ sid_file, strerror(errno)));
+ return False;
+ }
+ }
+
+ slprintf(file_name, sizeof(file_name)-1, "%s.SID", sam_name);
+ strupper(file_name);
+ pstrcat(sid_file, file_name);
+
+ if ((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
+ DEBUG(0,("unable to open or create file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ return False;
+ }
+
+ /*
+ * Check if the file contains data.
+ */
+
+ if (sys_fstat(fd, &st) < 0) {
+ DEBUG(0,("unable to stat file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+
+ if (st.st_size > 0)
+ {
+ /*
+ * We have a valid SID already.
+ */
+ close(fd);
+ DEBUG(0,("SID file %s already exists\n", sid_file));
+ return False;
+ }
+
+ if (!do_file_lock(fd, 60, F_WRLCK))
+ {
+ DEBUG(0,("unable to lock file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+
+ /*
+ * At this point we have a blocking lock on the SID
+ * file - check if in the meantime someone else wrote
+ * SID data into the file. If so - they were here first,
+ * use their data.
+ */
+
+ if (sys_fstat(fd, &st) < 0)
+ {
+ DEBUG(0,("unable to stat file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+
+ if (st.st_size > 0)
+ {
+ /*
+ * Unlock as soon as possible to reduce
+ * contention on the exclusive lock.
+ */
+ do_file_lock(fd, 60, F_UNLCK);
+
+ /*
+ * We have a valid SID already.
+ */
+
+ DEBUG(0,("SID file %s already exists\n", sid_file));
+ close(fd);
+ return False;
+ }
+
+ /*
+ * The file is still empty and we have an exlusive lock on it.
+ * Write out out SID data into the file.
+ */
+
+ if (fchmod(fd, 0644) < 0)
+ {
+ DEBUG(0,("unable to set correct permissions on file %s. \
+Error was %s\n", sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+
+ if (write(fd, sid_string, strlen(sid_string)) != strlen(sid_string))
+ {
+ DEBUG(0,("unable to write file %s. Error was %s\n",
+ sid_file, strerror(errno) ));
+ close(fd);
+ return False;
+ }
+
+ /*
+ * Unlock & exit.
+ */
+
+ do_file_lock(fd, 60, F_UNLCK);
+ close(fd);
+ return True;
+}
+
+/****************************************************************************
+create a random SID.
+****************************************************************************/
+BOOL create_new_sid(DOM_SID *sid)
+{
+ uchar raw_sid_data[12];
+ fstring sid_string;
+ int i;
+
+ /*
+ * Generate the new sid data & turn it into a string.
+ */
+ generate_random_buffer(raw_sid_data, 12, True);
+
+ fstrcpy(sid_string, "S-1-5-21");
+ for(i = 0; i < 3; i++)
+ {
+ fstring tmp_string;
+ slprintf(tmp_string, sizeof(tmp_string) - 1, "-%u", IVAL(raw_sid_data, i*4));
+ fstrcat(sid_string, tmp_string);
+ }
+
+ fstrcat(sid_string, "\n");
+
+ /*
+ * Ensure our new SID is valid.
+ */
+
+ if (!string_to_sid(sid, sid_string))
+ {
+ DEBUG(0,("unable to generate machine SID.\n"));
+ return False;
+ }
+
+ return True;
+}
+